C# WPF绑定到全局变量以更新UI
假设我有两个窗口和一个trayicon上下文菜单。每个窗口都有一个切换按钮,上下文菜单有一个可检查的菜单项。所有三个控件都设计用于显示和切换相同值的状态C# WPF绑定到全局变量以更新UI,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,假设我有两个窗口和一个trayicon上下文菜单。每个窗口都有一个切换按钮,上下文菜单有一个可检查的菜单项。所有三个控件都设计用于显示和切换相同值的状态 在本例中,我如何将三个控件绑定到一个全局变量,当其中一个控件被选中/取消选中时,其他控件将相应地更新?我应该只调用还是有MVVM解决方案?我是WPF新手,所以我不确定实现这一点的最佳/最正确的方法。您可以添加到codebehind bool IsChecked属性中,并将其用于所有您想要的组件。您可以将it组件的事件方法更改为true或fals
在本例中,我如何将三个控件绑定到一个全局变量,当其中一个控件被选中/取消选中时,其他控件将相应地更新?我应该只调用还是有MVVM解决方案?我是WPF新手,所以我不确定实现这一点的最佳/最正确的方法。您可以添加到codebehind bool IsChecked属性中,并将其用于所有您想要的组件。您可以将it组件的事件方法更改为true或false 您可以将bool IsChecked属性添加到codebehind中,并将其用于所需的所有组件。您可以将it组件的事件方法更改为true或false 假设您有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 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();
}
}
记住在一些长期存在的对象(如应用程序或主窗口)中至少保留一个对创建的CommonState的引用,这样它就不会在某个时候被垃圾收集
在XAML中,您应该使用RelativeSource进行绑定,以便创建的每种新类型的窗口都可以有自己的独立ViewModel(DataContext):
我演示的示例不是唯一的方法,我不会说“最好”,但它解决了以下问题:
如果任何人试图运行上述代码,请记住从App.xaml中删除StartupUri=“MainWindow.xaml”。假设您有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 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();
}
}
记住在一些长期存在的对象(如应用程序或主窗口)中至少保留一个对创建的CommonState的引用,这样它就不会在某个时候被垃圾收集
在XAML中,您应该使用RelativeSource进行绑定,以便创建的每种新类型的窗口都可以有自己的独立ViewModel(DataContext):
我演示的示例不是唯一的方法,我不会说“最好”,但它解决了以下问题:
如果任何人试图运行上述代码,请记住从App.xaml中删除StartupUri=“MainWindow.xaml”但不完全遵循。它是如何联系在一起的,从而使一个组件的更改更新所有其他组件的?下面不太清楚。如何将所有组件链接在一起,从而使一个组件的更改更新所有其他组件?到目前为止,这在两个窗口之间非常有效。如何将CommonState注入XAML定义的ContextMenu?我正在使用Hardcodet.Wpf.TaskbarNotification TaskbarIcon库。ContextMenu是在XAML ResourceDictionary中定义的。TaskbarIcon由FindResource在App.OnStartup.Add属性期间创建,如CommonState中的ICommand CommandA{get;set;},并初始化命令。然后像这样绑定命令:我得到一个错误:找不到用于绑定的源,引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel='1'。BindingExpression:Path=CommonState.IsCheck1;DataItem=null;目标元素是“MenuItem”(Name='mnuCheck1');目标属性为“Command”(类型为“ICommand”)。这里有更多的细节:。。。公共部分类NotifyIconResources:ResourceDictionary,ICommonState{(MenuEventHandlers)}RD如何获取CommonState引用?这在两个窗口之间非常有效。如何将CommonState注入XAML定义的ContextMenu?我正在使用Hardcodet.Wpf.TaskbarNotification TaskbarIcon库。ContextMenu是在XAML ResourceDictionary中定义的。TaskbarIcon由FindResource在App.OnStartup.Add属性期间创建,如CommonState中的ICommand CommandA{get;set;},并初始化命令。然后像这样绑定命令:我得到一个错误:找不到用于绑定的源,引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Window',AncestorLevel='1'。BindingExpression:Path=CommonState.IsCheck1;DataItem=null;目标元素是“MenuItem”(Name='mnuCheck1');目标属性为“命令”(ty)