0

まず、私はC#とモバイルアプリケーション開発でかなり新しいので、私の貧弱な説明には申し訳ありません。 IOSとAndroid用のXamarinクロスプラットフォームプロジェクトのページが必要です。 a.xamlとb.xamlと言うことができます。両方のページには、2つの異なる名前空間(たとえば、1番目と2番目)があります。 a.xamlにラベル(lblA)、b.xaml(btnB)にボタンがあるとします。私がしたいのは、btnBがクリックされたときにlblA.textを更新することです。私はx:Name = "btnB"を試しましたが、Second namespaceからbtnBにアクセスすることはできません。それを行う方法はありますか?xamlコントロールの値を別のcs/namespaceから複数のページに変更する

コンテキスト:今、私の問題の背景について説明しましょう。私は私のmultipageクロスプラットフォームプロジェクトでSignalRを実装しようとしています。別のsignalrクラスとメッセージ受信イベントで、別のページで関連するラベル/グリッドを更新したいと思います。したがって、すべてのページのコントロールにアクセスする必要があります。 Debug.Writeline( "signalrから受信したメッセージ")を実行しようとすると問題なく動作しますが、First.lblA.textを変更しようとすると何の例外もスローされません。

したがって、どんな提案も高く評価されます。

おかげ

SignalR.cs:

using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Microsoft.AspNet.SignalR.Client; 
using System.Collections.Generic; 
using Xamarin.Forms; 

namespace SigClient 
{ 

    public class Client 
    { 
     public string _user = ""; 
     public string _prefix = ""; 
     public string _url = ""; 
     public int _port = 80; 

     public string User 
     { 
      get 
      { 
       return _user; 
      } 
      set 
      { 
       _user = value; 
      } 
     } 
     public string Prefix 
     { 
      get 
      { 
       return _prefix; 
      } 
      set 
      { 
       _prefix = value; 
      } 
     } 
     public string HubUrl 
     { 
      get 
      { 
       return _url; 
      } 
      set 
      { 
       _url = value; 
      } 
     } 
     public int Port 
     { 
      get 
      { 
       return _port; 
      } 
      set 
      { 
       _port = value; 
      } 
     } 


     private HubConnection _connection; 
     private IHubProxy _proxy; 


     public void Clients() 
     { 
      var querystringData = new Dictionary<string, string>(); 
      querystringData.Add("userName", "{\"userName\":\"" + _prefix + "_" + "driver" + _user + "\"}"); 
      _connection = new HubConnection(_url + ":" + _port.ToString(), querystringData); 
      _proxy = _connection.CreateHubProxy("MyHub"); 
     } 

     private App1.MainPage page; 
     public Label lbl; 
     public async Task Connect() 
     { 
      try 
      { 
       page = new App1.MainPage(); 
       _proxy.On<string, string>("addNewMessageToPage", (name, msg) => 
       //-> I want to update testlbl.text=msg 
       //page.exLbl.Text = msg //doesnt do anything 
       //Debug.WriteLine(msg) //This line works fine 
       deb("", msg) 

       ); 
      } 
      catch(Exception ex) 
      { 
       Debug.WriteLine(ex.Message); 
      } 


      await _connection.Start(); 
     } 

     public async Task deb(string msg, string msg1) 
     { 
      //page.exLbl.Text = msg1 
      page.DoStuff(msg1); 
      lbl = page.exLbl; 
      lbl.Text = msg1; 
      Debug.WriteLine(msg + "-" + msg1); 
     } 
     public Task Send(string message) 
     { 
      Debug.WriteLine("SignalR message sent"); 
      return _proxy.Invoke("SendToOperators", "eb5_operator123456", "NewJobSaved", "system"); 
     } 
    } 
} 

MainPage.xamlを:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:App1" 
      x:Class="App1.MainPage" 
      x:FieldModifier="public"> 
    <StackLayout VerticalOptions="Center" HorizontalOptions="Center"> 
     <Label Text="Welcome to Xamarin Forms!" 
       VerticalOptions="Center" 
       HorizontalOptions="Center" ></Label> 
     <Label x:Name="testLbl" VerticalOptions="Center" HorizontalOptions="Center" x:FieldModifier="public"></Label> 
     <Button x:Name="testBtn" Text="Connect"></Button> 
     <Button x:Name="testSend" Text="Send Msg"></Button> 
    </StackLayout> 
</ContentPage> 

MainPage.xaml.cs:再び

using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Xamarin.Forms; 
using SigClient; 
using UIKit; 


namespace App1 
{ 
    public partial class MainPage : ContentPage 
    { 
     public Label exLbl 
     { 
      get; set; 
     } 

     public Client cclient=new Client(); 
     public MainPage() 
     { 
      InitializeComponent(); 
      testLbl.Text = "I'm Loaded..."; 

      cclient.User = "111"; 
      cclient.Prefix = "xxx"; 
      cclient.HubUrl = "http://255.255.255.255"; 
      cclient.Port = 80; 

      testBtn.Clicked += new EventHandler(testBtn_Click); 
      testSend.Clicked += new EventHandler(testSend_Click); 
     } 

     async void testSend_Click(Object sender, EventArgs e) 
     { 
      try 
      { 
       await cclient.Send("test"); 
       testLbl.Text = "Sent!!!"; 
      } 
      catch (Exception ex) 
      { 
       testLbl.Text = ex.Message; 
      } 
     } 
     async void testBtn_Click(Object sender, EventArgs e) 
     { 
      try 
      { 
       cclient.Clients(); 
       await cclient.Connect(); 
       testLbl.Text = "Connected!!!"; 
      } 
      catch(Exception ex) 
      { 
       testLbl.Text = ex.Message; 

      } 
     } 
     public void DoStuff(string x) 
     { 
      this.testLbl.Text=x; //this line doesnt response 
      Debug.WriteLine(x+"dostuff"); //this line works fine 
     } 
    } 
} 

は、私はあなたの許しを請います私の初心者のコーディングスタイリングのためにe。お気軽に質問してください。 .NETの既定のコントロールによって

おかげ

+0

あなたは一度に1ページ目に見える持っていてすることができます現在表示されていないページを更新してはいけません。なぜなら、あなたがしようとしていることは良いもののようには見えませんアプローチ。後であなたのアプリページから消費される可能性があるSignalRクライアントからの公開イベントを公開し、そこで状態を更新するのはなぜですか?または、MessagingCenterを使用することもできます。 – apineda

+0

ねえ、あなたの提案に感謝します。それについてのいくつかの記事を読んで、それは有望に見えます。私は次の数日間オフになり、私が戻ってきたときにそれを撃つ。それがうまくいくことを望みます。ありがとう –

答えて

0

は保護されていますので、それらは公にアクセスすることができます。コントロールを公開することは常に可能です。

たとえば、クラスAでは、保護されたコントロールを返すreadonlyプロパティを定義できます。

public class A { 
    public Label LblA { get {return lblA;}} 
} 

in Bは、現在公開されているためLblAにアクセスできます。

public class B { 
    private A aRef; /*a reference to an actual instance of A*/ 
    public void setALabel() { 
     aRef.LblA.text="Some Text"; 
    } 
} 

コードでは、クライアントは接続時にメインページの新しいインスタンスを作成しています。コードが動作するためには、クライアントクラスのpage変数はすでに作成されたページへの参照を保持する必要があります。

SignalR.cs:

using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Microsoft.AspNet.SignalR.Client; 
using System.Collections.Generic; 
using Xamarin.Forms; 

namespace SigClient 
{ 

    public class Client 
    { 
     public string _user = ""; 
     public string _prefix = ""; 
     public string _url = ""; 
     public int _port = 80; 

     public string User 
     { 
      get 
      { 
       return _user; 
      } 
      set 
      { 
       _user = value; 
      } 
     } 
     public string Prefix 
     { 
      get 
      { 
       return _prefix; 
      } 
      set 
      { 
       _prefix = value; 
      } 
     } 
     public string HubUrl 
     { 
      get 
      { 
       return _url; 
      } 
      set 
      { 
       _url = value; 
      } 
     } 
     public int Port 
     { 
      get 
      { 
       return _port; 
      } 
      set 
      { 
       _port = value; 
      } 
     } 


     private HubConnection _connection; 
     private IHubProxy _proxy; 


     public void Clients(App1.MainPage page) 
     { 
      this.page=page; 
      var querystringData = new Dictionary<string, string>(); 
      querystringData.Add("userName", "{\"userName\":\"" + _prefix + "_" + "driver" + _user + "\"}"); 
      _connection = new HubConnection(_url + ":" + _port.ToString(), querystringData); 
      _proxy = _connection.CreateHubProxy("MyHub"); 
     } 

     private App1.MainPage page; 
     //public Label lbl; 
     public async Task Connect() 
     { 
      try 
      { 
       _proxy.On<string, string>("addNewMessageToPage", (name, msg) => 

       page.PublicLbl.Text = msg 
       //Debug.WriteLine(msg) //This line works fine 
       deb("", msg) 

       ); 
      } 
      catch(Exception ex) 
      { 
       Debug.WriteLine(ex.Message); 
      } 


      await _connection.Start(); 
     } 

     public async Task deb(string msg, string msg1) 
     { 
      //you don't need both of these lines 
      page.PublicLbl.Text = msg1 
      page.DoStuff(msg1); 
      Debug.WriteLine(msg + "-" + msg1); 
     } 
     public Task Send(string message) 
     { 
      Debug.WriteLine("SignalR message sent"); 
      return _proxy.Invoke("SendToOperators", "eb5_operator123456", "NewJobSaved", "system"); 
     } 
    } 
} 

MainPage.xamlを:

<?xml version="1.0" encoding="utf-8" ?> 
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
      xmlns:local="clr-namespace:App1" 
      x:Class="App1.MainPage" 
      x:FieldModifier="public"> 
    <StackLayout VerticalOptions="Center" HorizontalOptions="Center"> 
     <Label Text="Welcome to Xamarin Forms!" 
       VerticalOptions="Center" 
       HorizontalOptions="Center" ></Label> 
     <Label x:Name="testLbl" VerticalOptions="Center" HorizontalOptions="Center"></Label> 
     <Label x:Name="clientLbl" VerticalOptions="Center" HorizontalOptions="Center"></Label> 
     <Button x:Name="testBtn" Text="Connect"></Button> 
     <Button x:Name="testSend" Text="Send Msg"></Button> 
    </StackLayout> 
</ContentPage> 

MainPage.xaml.cs:

using System; 
using System.Diagnostics; 
using System.Threading.Tasks; 
using Xamarin.Forms; 
using SigClient; 
using UIKit; 


namespace App1 
{ 
    public partial class MainPage : ContentPage 
    { 
     public Label PublicLbl 
     { 
      get {return clientLbl;} 
     } 

     public Client cclient 
     public MainPage() 
     { 
      InitializeComponent(); 
      cclient=new Client(this); 
      testLbl.Text = "I'm Loaded..."; 

      cclient.User = "111"; 
      cclient.Prefix = "xxx"; 
      cclient.HubUrl = "http://255.255.255.255"; 
      cclient.Port = 80; 

      testBtn.Clicked += new EventHandler(testBtn_Click); 
      testSend.Clicked += new EventHandler(testSend_Click); 
     } 

     async void testSend_Click(Object sender, EventArgs e) 
     { 
      try 
      { 
       await cclient.Send("test"); 
       testLbl.Text = "Sent!!!"; 
      } 
      catch (Exception ex) 
      { 
       testLbl.Text = ex.Message; 
      } 
     } 
     async void testBtn_Click(Object sender, EventArgs e) 
     { 
      try 
      { 
       cclient.Clients(); 
       await cclient.Connect(); 
       //this line will going to overwrite the client message in the original code 
       testLbl.Text = "Connected!!!"; 
      } 
      catch(Exception ex) 
      { 
       testLbl.Text = ex.Message; 

      } 
     } 
     public void DoStuff(string x) 
     { 
      this.clientLbl.Text = x; 
      Debug.WriteLine(x + " dostuff"); //this line works fine 
     } 
    } 
} 
+0

ちょうど今試みたが、didntの仕事。メインページの変更:public Label exLbl {get {return testLbl; }}とSinalr.cs:private App1.MainPageページ。 プライベートラベルlbl; public asyncタスクConnect() { try { ページ=新しいApp1.MainPage(); _proxy.On <文字列、文字列>( "addNewMessageToPage"、(名前、MSG)=> page.exLbl.Text = MSG //Debug.WriteLine(msg) // DEB( ""、MSG) ); }。あなたの迅速なresposneありがとう –

+0

ページ=新しいApp1.MainPage(); MainPageの新しいインスタンスを作成しています。クライアントが既に新しいインスタンスを作成していないと見なす既存のインスタンスを参照する必要があります。 –

+0

たとえば、メインページのコンストラクタで 'cclient.page = this;'を追加し、クライアントで 'private App1.MainPage page;'を 'public App1.MainPage page;'に変更するか、メインページをパラメータとしてクライアントに渡しますクライアントコンストラクタでプライベート変数を設定する –

関連する問題