0

d'abord je suis désolé pour ma pauvre explication car je suis assez nouveau dans le développement de C# et d'applications mobiles. J'ai des pages dans mon projet de plate-forme Xamarin pour IOS et Android. Disons a.xaml et b.xaml. Les deux pages ont deux espaces de noms différents (par exemple premier et deuxième). Disons que j'ai une étiquette (lblA) dans a.xaml et un bouton dans b.xaml (btnB). Ce que je veux faire est de mettre à jour lblA.text quand on clique sur btnB. J'ai essayé x: Name = "btnB" mais je ne peux pas accéder à btnB à partir de Second namespace. Y-a-t-il un moyen de faire ça?changez la valeur de xaml control en plusieurs pages d'un cs/namespace séparé

Contexte: Maintenant, laissez-moi vous expliquer l'arrière-plan de mon problème. J'essaie de mettre en œuvre SignalR dans mon projet multi-plateformes multi-pages. Lorsque j'ai une classe signalr séparée et un événement message reçu, je veux mettre à jour l'étiquette/grille pertinente dans différentes pages. Par conséquent, j'ai besoin d'accéder aux contrôles dans toutes mes pages. Quand j'essaie d'exécuter Debug.Writeline ("message reçu de signalr") cela fonctionne parfaitement bien mais quand j'essaye de changer First.lblA.text cela ne marche pas et il n'y a aucune exception.

Par conséquent, toutes les suggestions seront très appréciées.

Merci

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 
     } 
    } 
} 

Encore une fois, je vous demande pardon pour mon style de codage novice e. N'hésitez pas à me poser des questions.

Merci

+0

Vous ne pouvez avoir 1 page visible au moment et vous ne devrait pas mettre à jour les pages qui ne sont pas visibles actuellement puisque vous ne connaissez pas l'état de celles-ci, en disant que ce que vous essayez de faire ne semble pas être un bon approche. Pourquoi n'exposez-vous pas les événements publics du client SignalR qui peuvent être consommés par la suite à partir de vos pages d'applications et là vous mettez à jour l'état?Ou vous pouvez même utiliser le MessagingCenter. – apineda

+0

Hey, merci pour votre suggestion. Il suffit de lire quelques articles à ce sujet et il semble prometteur. Je serai en congé pour les prochains jours et quand je reviendrai, je tenterai. Esperons que ça marche. Merci –

Répondre

0

par les contrôles par défaut en .Net sont protégés afin qu'ils puissent être accessibles au public. Vous pouvez toujours exposer le contrôle publiquement.

Par exemple, dans la classe A, vous pouvez définir une propriété readonly qui renvoie le contrôle protégé.

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

Le dans B, vous pouvez accéder à LblA parce qu'il est maintenant public.

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

Dans votre code, le client crée une nouvelle instance de la page principale lors de la connexion. Pour que le code fonctionne, la variable de page de la classe client doit contenir une référence à la page qui a déjà été créée.

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

Juste maintenant essayé mais n'a pas fonctionné. Changement dans MainPage: public Label exLbl {get {return testLbl; }} et dans Sinalr.cs: page App1.MainPage privée; private Label lbl; public async Task Connect() { essayez { page = new App1.MainPage(); _proxy.On ("addNewMessageToPage", (nom, msg) => page.exLbl.Text = msg //Debug.WriteLine(msg) // deb ("", msg) ) }. Merci pour votre réponse rapide –

+0

page = new App1.MainPage(); est en train de créer une nouvelle instance de MainPage. Vous devriez référencer une instance existante que le client voit déjà ne pas en créer une nouvelle. –

+0

Par exemple, dans le constructeur de votre page principale, ajoutez 'cclient.page = this;' et dans le client changez la page privée App1.MainPage; 'à la page publique App1.MainPage;' ou passez la page principale en tant que paramètre au client constructeur et définir la variable privée dans le constructeur client –