从单独的 CS/命名空间更改多个页面中的 XAML 控件的值



首先,我很抱歉我的解释很糟糕,因为我在 C# 和移动应用程序开发方面相当陌生。 我必须在我的 Xamarin 跨平台项目中为 IOS 和 Android 提供页面。假设a.xaml和b.xaml。这两个页面都有两个不同的命名空间(例如第一个和第二个(。假设我在a.xaml中有一个标签(lblA(,在b.xaml(btnB(中有一个按钮。我想做的是在单击btnB时更新lblA.text。我尝试了x:Name="btnB",但无法从第二个命名空间访问btnB。有没有办法做到这一点?

背景:现在让我解释一下我的问题的背景。我正在尝试在我的多页跨平台项目中实现 SignalR。在我有一个单独的信号器类和消息接收事件的地方,我想更新不同页面中的相关标签/网格。因此,我需要访问所有页面中的控件。当我尝试执行 Debug.Writeline("从信号器接收的消息"(时,它工作得很好,但是当我尝试更改 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
}
}
}

再次,请原谅我的新手编码风格。请随时问我任何问题。

谢谢

默认情况下,.Net 中的控件受到保护,因此可以公开访问它们。您始终可以公开控件。

例如,在类 A 中,可以定义返回受保护控件的只读属性。

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

在 B 中,您可以访问 LblA,因为它现在是公开的。

public class B {
private A aRef; /*a reference to an actual instance of A*/
public void setALabel() {
aRef.LblA.text="Some 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(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
}
}
}

最新更新