C# 从任何地方更改控件

C# 从任何地方更改控件,c#,button,xamarin.forms,xamarin.android,xamarin.ios,C#,Button,Xamarin.forms,Xamarin.android,Xamarin.ios,我想做的是: 我想在我的代码中的任何地方更改按钮的背景色(Xamarin表单中的其他类)。例如,a页中的按钮a会更改B页中按钮B的颜色 在Windows上,您可以使用Android/iOS上没有的。 你能给我一个提示吗 在使用MVVM方法之前,我用按钮的文本进行了尝试 在我的PageB.xaml中: <Button Name="Button_B" Text="{Binding MyText}"/> 在我的MVVMPageB.cs中 priva

我想做的是:

我想在我的代码中的任何地方更改按钮的背景色(Xamarin表单中的其他类)。例如,a页中的按钮a会更改B页中按钮B的颜色

在Windows上,您可以使用Android/iOS上没有的。 你能给我一个提示吗

在使用MVVM方法之前,我用按钮的文本进行了尝试

在我的PageB.xaml中:

<Button Name="Button_B" Text="{Binding MyText}"/>
在我的MVVMPageB.cs中

private string myText;
public string MyText
{ 
get => mytring;
set
{
mystring = value;
PropertyChanged?
.Invoke(this, new PropertyChangedEventArgs(MyText)));
}
如果我打电话:

MyText("Test");
在我的MVVMPageB.cs中,它运行良好。但是我不知道如何从其他任何地方访问这个。 我试过:


技术1

这是MVVMPageB的单例模式

MVVMPageB.It.MyText("Test");
如果您从未有过两个页面B”,则此功能有效如果导航堆栈上有一个页面B(因此您可以“返回”到该页面),并且您显示另一个页面B,这将无法正常工作,因为两个页面B都将引用相同的MVVMPageB实例

public class MVVMPageB : ...
{
    // "Singleton": This is the only instance of MVVMPageB.
    private static MVVMPageB _It;
    public static MVVMPageB It
    {
        if (_It == null)
            _It = new MVVMPageB();
        return _It;
    }

    // Your constructor.
    // It is private; only used via "It" getter above.
    private MVVMPageB()
    {
        ...
    }
}
另一个类中的代码,以访问MVVMPageB的成员

MVVMPageB.It.MyText("Test");
替换此代码:

BindingContext = new MVVMPageB();
BindingContext = MVVMPageB.It;
使用此代码:

BindingContext = new MVVMPageB();
BindingContext = MVVMPageB.It;
注意:因为
MVVMPageB.It
是静态的,如果您第二次转到B页,它将显示您上次使用的值(在同一个应用程序会话中)


技术2

一种更健壮的方法,即使您创建了另一个页面B也能工作,需要有某种方式将MVVMPageB的当前实例传递给MVVMPageA或PageA

完整的示例取决于您创建每个页面的方式/位置。但这表明了这个想法

public class MVVMPageB : ...
{
    // Your constructor. Add parameters as needed.
    public MVVMPageB()
    {
        ...
    }
}

public partial class PageB : ...
{
    // Convenience property - our BindingContext is type MVVMPageB.
    public MVVMPageB VMb => (MVVMPageB)BindingContext;
    ...
}

public class MVVMPageA : ...
{
    // This is here, so both MVVMPageA and PageA can find it.
    public MVVMPageB VMb;
}

public partial class PageA : ...
{
    // Convenience property - our BindingContext is type MVVMPageA.
    public MVVMPageA VMa => (MVVMPageA)BindingContext;
    ...
}
    
创建B页和A页的代码:

var pageB = new PageB();
var pageA = new PageA();
// Tell MVVMPageA about MVVMPageB.
pageA.VMa.VMb = pageB.VMb;
MVVMPageA中的方法现在可以访问MVVMPageB的成员:

VMb.MyText("Test");
VMa.VMb.MyText("Test");
PageA中的方法现在可以访问MVVMPageB的成员:

VMb.MyText("Test");
VMa.VMb.MyText("Test");

注意:在这种动态技术中,如果您第二次转到页面B(在同一个应用程序会话中),它将有一个新的MVVMPageB实例。

您需要一个singleton viewModel用于此用途。我通常使用一个导航栏。
MVVMPageB.It.MyText("Test");
因此,每个作用域页面viewModel都会引用其中的单例全局viewModel:

PageAViewModel具有属性NavBarModel
PageBViewModel具有属性NavBarModel
等等

所以很明显你的按钮会被绑定
BackgroundColor={Binding NavBarModel.ActionColor}
在每个不同的页面上。
现在要创建一个单例并获取其引用,我可以看到两种方法:依赖项注入(DI)或单实例创建。您可以在网上阅读很多关于DI的信息,而对于一个简单的案例,您可以使用一个带有道具的单实例模型,如:

private NavBarModel _current;
public NavBarModel Current
{
    get
    {
        if (_current == null)
            _current = new NavBarModel();
        return _current;
    }
}
然后在页面中查看模型构造函数集
NavBarModel=NavBarModel.Current


不过,您需要DI来引用singleton中的更多模型,或/或使代码更加可重用。祝你好运。

这听起来像是一个可怕的设计,不同页面上的控件直接与彼此的UI交互。将MessagingCenter视为在断开连接的网络之间传递消息的一种方式pages@ToolmakerSteve我尝试了mvvm方法,但找不到调用函数的方法。我尝试了使用XML MVVM.cs string mytext Public string mytext get set等字符串进行sonehing。frim m PageB.cs我可以调用Mytext(“测试”),按钮文本会发生变化。但是我怎样才能从PageB.cs中实现这一点呢?好的,我需要30分钟的即时消息而不是PC,这是一个内容页面,如果这是有用的信息,我可以通过Shell选项卡栏获取。@ToolmakerSteve我发布了我的MVVM方法。对不起,我没有正确理解你的评论。我不知道是否有太多的要求,但你能从上面纠正我的方法吗?(当然,如果不是完全错误的话)在你写这篇文章的时候,我提交了一份更详细的答案,这是根据OP的情况量身定做的。如果你有机会的话,请看一下我的答案,提出任何建议。对此我感激不尽!!我尝试了你的第二个技巧,这是一个彻底的胜利D