我们说我有两个窗口和一个trayicon上下文菜单。每个窗口都有一个togglebutton,上下文菜单有一个可检查的菜单项。所有三个控件都旨在显示和切换相同值的状态。
如何将三个控件中的三个控件绑定到单个全局变量(在这种情况下为IsChecked),当检查/取消选中其中一个控件时,其他控件将相应更新?我应该只是进行调用还是有MVVM解决方案?我是WPF的新手,所以我不确定最好/最正确的方法。
答案 0 :(得分:1)
假设您有WindowA,WindowB,...,WindowN并假设它们都是不同类型的。
创建一个类,比如CommonState,它封装了所有常见属性,命令等,实现了INotifyPropertyChanged
public class CommonState : INotifyPropertyChanged
{
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
private bool _isChecked;
public bool IsChecked
{
get { return _isChecked; }
set
{
if (value != _isChecked)
{
_isChecked = value;
OnPropertyChanged();
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
然后声明一个接口:
public interface ICommonStateWindow
{
CommonState { get; set; }
}
让每个窗口实现此接口:
public partial class WindowA : Window, ICommonState
{
public WindowA()
{
InitializeComponent();
}
// This property will be injected, do not re-assign
public CommonState CommonState { get; set; }
}
在显示之前在每个窗口中注入公共状态,例如:
public partial class App : Application
{
private CommonState _state;
protected override void OnStartup(StartupEventArgs e)
{
_state = new CommonState() {IsChecked = true};
var wndA = new WindowA() { CommonState = _state };
var wndB = new WindowB() { CommonState = _state };
wndA.Show();
wndB.Show();
}
}
请记住在一些长生命对象(如App或主窗口)中至少保留一个对创建的CommonState的引用,因此它不会在某个时刻收集垃圾。
在XAML中,您应该使用RelativeSource进行绑定,这样您创建的每种新类型的窗口都可以拥有自己独立的ViewModel(DataContext):
<Window x:Class="Example.WindowA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WindowA" Height="300" Width="300">
<Grid>
<CheckBox IsChecked="{Binding CommonState.IsChecked, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
</Grid>
</Window>
这个例子,我演示的不是唯一的方式,我不会说&#34;最好的&#34;,但它解决了以下问题:
另一种可能的解决方案是将CommonState的单例实例注册到静态公开的控制容器(IoC)反转中,并使每个具体窗口的ViewModel获得一个实例。这样您就可以避免注射步骤。对于小型项目来说,这将是一种过度杀伤
我有人试图运行上面的代码,记得删除StartupUri =&#34; MainWindow.xaml&#34;来自App.xaml
答案 1 :(得分:0)
您可以添加到您的代码隐藏bool IsChecked属性,并将其用于您想要的所有组件。你可以改变它的组件&#39; event方法为true或false。