从任何地方更改控件
Changing Controls from anywhere
我想做的事情:
我想在我的代码中的任何位置更改按钮的背景颜色(其他 类 Xamarin Forms)。例如,页面 A 中的按钮 A 更改页面 B 中按钮 B 的颜色
在 Windows 上,您可以使用 MethodInvoker Delegat,但在 Android/iOS 上不可用。
你能给我一个提示吗?
我之前用 MVVM 方法尝试过使用按钮的文本。
在我的 PageB.xaml:
<Button Name="Button_B" Text="{Binding MyText}"/>
在我的 PageB.cs 在 public 页面 B
BindingContext = new MVVMPageB();
在我的 MVVM 中PageB.cs
private string myText;
public string MyText
{
get => mytring;
set
{
mystring = value;
PropertyChanged?
.Invoke(this, new PropertyChangedEventArgs(MyText)));
}
如果我打电话:
MyText("Test");
在我的 MVVMPageB.cs 中它工作正常。但我不知道如何从其他任何地方访问它。
我试过了:
var Testobjekt = new MVVMPageB() //pretty sure thats not correct
Testobjekt.MyText("Test"); //wont work
技术 1
这是 MVVMPageB 的单例模式。
如果您从来没有两个“页面 B”,这将有效。 IF 导航堆栈上有一个页面 B(因此您可以“返回”到它),然后显示另一个页面 B,THEN这不会很好地工作,因为两个页面 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()
{
...
}
}
另一个class中的代码,用于访问MVVMPageB的成员。
MVVMPageB.It.MyText("Test");
替换此代码:
BindingContext = new MVVMPageB();
使用此代码:
BindingContext = MVVMPageB.It;
注意:因为 MVVMPageB.It
是静态的,如果您第二次访问页面 B,它将显示您上次(在同一个应用程序会话中)的值。
技巧二
一种更稳健的方法,即使您创建另一个页面 B 也能工作,需要有某种方法将 MVVMPageB 的当前实例传递给 MVVMPageA 或 PageA。
一个完整的示例完全取决于 how/where 您创建的每个页面。但这表明了这个想法。
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");
PageA 中的方法现在可以访问 MVVMPageB 的成员:
VMa.VMb.MyText("Test");
注意:在这种动态技术中,如果您第二次访问页面 B(在同一个应用程序会话中),它将有一个新的 MVVMPageB 实例。
您需要一个单独的 viewModel 才能使用。我通常将一个用于导航栏。
所以每个作用域页面 viewModel 都引用里面的单例全局 viewModel:
PageAViewModel 有 属性NavBarModel
PageBViewModel 有 属性 NavBarModel
等等..
所以很明显你的按钮将被绑定为
BackgroundColor={Binding NavBarModel.ActionColor}
在每个不同的页面上。
现在要有一个单例并获取它的引用,我可以看到两种方法:依赖注入 (DI) 或创建单实例。您可以在网上阅读很多关于 DI 的信息,而对于一个简单的案例,您可以拥有一个带有 prop 的单实例模型:
private NavBarModel _current;
public NavBarModel Current
{
get
{
if (_current == null)
_current = new NavBarModel();
return _current;
}
}
然后在页面 viewModels 构造函数中设置 NavBarModel = NavBarModel.Current;
尽管您需要 DI 以在单例中引用更多模型,or/and 使您的代码更可重用。祝你好运。
我想做的事情:
我想在我的代码中的任何位置更改按钮的背景颜色(其他 类 Xamarin Forms)。例如,页面 A 中的按钮 A 更改页面 B 中按钮 B 的颜色
在 Windows 上,您可以使用 MethodInvoker Delegat,但在 Android/iOS 上不可用。 你能给我一个提示吗?
我之前用 MVVM 方法尝试过使用按钮的文本。
在我的 PageB.xaml:
<Button Name="Button_B" Text="{Binding MyText}"/>
在我的 PageB.cs 在 public 页面 B
BindingContext = new MVVMPageB();
在我的 MVVM 中PageB.cs
private string myText;
public string MyText
{
get => mytring;
set
{
mystring = value;
PropertyChanged?
.Invoke(this, new PropertyChangedEventArgs(MyText)));
}
如果我打电话:
MyText("Test");
在我的 MVVMPageB.cs 中它工作正常。但我不知道如何从其他任何地方访问它。 我试过了:
var Testobjekt = new MVVMPageB() //pretty sure thats not correct
Testobjekt.MyText("Test"); //wont work
技术 1
这是 MVVMPageB 的单例模式。
如果您从来没有两个“页面 B”,这将有效。 IF 导航堆栈上有一个页面 B(因此您可以“返回”到它),然后显示另一个页面 B,THEN这不会很好地工作,因为两个页面 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()
{
...
}
}
另一个class中的代码,用于访问MVVMPageB的成员。
MVVMPageB.It.MyText("Test");
替换此代码:
BindingContext = new MVVMPageB();
使用此代码:
BindingContext = MVVMPageB.It;
注意:因为 MVVMPageB.It
是静态的,如果您第二次访问页面 B,它将显示您上次(在同一个应用程序会话中)的值。
技巧二
一种更稳健的方法,即使您创建另一个页面 B 也能工作,需要有某种方法将 MVVMPageB 的当前实例传递给 MVVMPageA 或 PageA。
一个完整的示例完全取决于 how/where 您创建的每个页面。但这表明了这个想法。
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");
PageA 中的方法现在可以访问 MVVMPageB 的成员:
VMa.VMb.MyText("Test");
注意:在这种动态技术中,如果您第二次访问页面 B(在同一个应用程序会话中),它将有一个新的 MVVMPageB 实例。
您需要一个单独的 viewModel 才能使用。我通常将一个用于导航栏。
所以每个作用域页面 viewModel 都引用里面的单例全局 viewModel:
PageAViewModel 有 属性NavBarModel
PageBViewModel 有 属性 NavBarModel
等等..
所以很明显你的按钮将被绑定为
BackgroundColor={Binding NavBarModel.ActionColor}
在每个不同的页面上。
现在要有一个单例并获取它的引用,我可以看到两种方法:依赖注入 (DI) 或创建单实例。您可以在网上阅读很多关于 DI 的信息,而对于一个简单的案例,您可以拥有一个带有 prop 的单实例模型:
private NavBarModel _current;
public NavBarModel Current
{
get
{
if (_current == null)
_current = new NavBarModel();
return _current;
}
}
然后在页面 viewModels 构造函数中设置 NavBarModel = NavBarModel.Current;
尽管您需要 DI 以在单例中引用更多模型,or/and 使您的代码更可重用。祝你好运。