我有一个名为AppContext
的Singleton对象(实现INotifyPropertyChanged
),里面有IsLogged
属性。
public class AppContext : INotifyPropertyChanged {
private static AppContext instance;
public AppContext() { }
public static AppContext Instance {
get => instance ?? (instance = new AppContext());
}
static bool _isLogged = true;
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public bool IsLogged {
get => _isLogged;
set {
_isLogged = value;
Console.WriteLine("islogged = {0}", value);
OnPropertyChanged();
}
}
}
我在StaticResource
Application.Resources
中存储AppContext
,该App.xaml
引用文件<Application.Resources>
<local:AppContext x:Key="AppContext"/>
</Application.Resources>
中的Window
:
<CheckBox IsChecked="{Binding Source={StaticResource AppContext}, Path=IsLogged}"/>
我有两个不同的IsLogged
,其中有相同的复选框声明:
private void Button_Click(object sender, RoutedEventArgs e) {
AppContext.Instance.IsLogged = !AppContext.Instance.IsLogged;
}
这是我的问题:
当我选中/取消选中两个窗口之一的复选框时,它运行良好(两个复选框保持相同的状态)。
但是,如果我添加一个按钮,在点击时会更改{{1}}的状态,则不会更新复选框。
{{1}}
答案 0 :(得分:1)
你的问题的根源在于你的AppContext
类并不是一个单独的 - 它有一个允许创建任意数量实例的公共构造函数。这恰好发生了什么 - 这段代码:
<Application.Resources>
<local:AppContext x:Key="AppContext"/>
</Application.Resources>
创建一个新实例而不是引用(预期)单例实例 - 请注意此代码中没有对AppContext.Instance
属性的引用。这个新创建的实例在您的窗口之间共享(因此检查/取消选中工作),但是当您修改AppContext.Instance
对象时,您实际上修改的对象不同于您的复选框所绑定的对象。
为了修复您的代码,您应该修改您的绑定以使用AppContext.Instance
作为来源:
<CheckBox IsChecked="{Binding Source={x:Static local:AppContext.Instance}, Path=IsLogged}"/>
或者,如果您想保留绑定并将单例作为资源,则应修改"AppContext"
资源以引用AppContext.Instance
属性:
<Application.Resources>
<x:Static x:Key="AppContext" MemberType="{x:Type local:AppContext}" Member="Instance" />
</Application.Resources>
此外,虽然没有必要解决此问题,但我建议将AppContext
构造函数设为私有,以便您遵循单例模式并且不会意外创建新实例。
答案 1 :(得分:0)
问题是,我的媒体资源Instance
正在StaticResource
文件中App.xaml
创建一个不同的实例...
我最后将其添加到App.xaml.cs
:
static AppContext _context;
public static AppContext Context {
get => _context ?? (_context = (AppContext) Current.Resources["AppContext"]);
}
现在我在按钮中使用它:
App.Context.IsLogged = !App.Context.IsLogged;
有了这个,只有一个例子。
但如果你有更好的方法来做到这一点,我很感兴趣:)