C# 无法理解INotifyPropertyChanged的实现
我只是C#的新手,我在MSDN博客上读到了关于INotifyPropertyChanged事件处理程序的C# 无法理解INotifyPropertyChanged的实现,c#,xaml,uwp,C#,Xaml,Uwp,我只是C#的新手,我在MSDN博客上读到了关于INotifyPropertyChanged事件处理程序的INotifyPropertyChanged事件处理程序,并在这里的“stackoverflow”上搜索。但我并不真正理解如何在代码中实现它,以及如何将事件和属性绑定在一起。 我已经用INotifyPropertyChanged创建了一个BindingClass,代码是: namespace Testing.Pages { class BindingClass : INotifyPrope
INotifyPropertyChanged事件处理程序
,并在这里的“stackoverflow”上搜索。但我并不真正理解如何在代码中实现它,以及如何将事件和属性绑定在一起。我已经用
INotifyPropertyChanged
创建了一个BindingClass
,代码是:namespace Testing.Pages
{
class BindingClass : INotifyPropertyChanged
{
private string _setting;
public event PropertyChangedEventHandler PropertyChanged;
public BindingClass()
{
}
public BindingClass(string value)
{
_setting = value;
}
public string SettingProperty
{
get { return _setting; }
set
{
_setting = value;
// calling OnPropertyChanged whenever the property gets updated
}
}
protected void OnPropertyChanged([CallerMemberName] string _setting = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_setting));
}
}
}
SettingsPage.xaml
我已经在使用
int notifySettings
在localsettings文件夹中更改应用程序的设置,每次应用程序重新启动时,它都会在app.xaml
中加载设置。每次更改设置时,我都会调用另一个类中的函数,当我在SettingsPage.xaml
中单击这两个单选按钮之一时,它会更改设置并播放动画。这是老办法。
现在我想将这些事件绑定在一起,这样我就不必使用int notifySettings
,而且每当主题设置更新时,PopupText
动画应该像以前一样播放。这也是我如何了解INotifyPropertyChanged事件的方法。
int notifySettings
传递一个int
值以相应地更改设置。
1=光主题,2=暗主题。
以下是设置类
:
如果仍然有任何歧义,请让我知道,我可以尝试进一步解释。我希望有人能在这方面帮助我。
更新:
我根据Danny Bogers的回答对我的项目进行了更改,但所需的动画没有启动,我认为这是因为该函数甚至没有被调用。我做了更多的改变,并尝试自己做一些事情,但没有真正起作用,所以我将使用自己的方法进行更改,直到其他人提出解决方案。我不是最擅长解释事情的人,我希望你能理解其中的要点!
我也没有时间对它进行适当的测试,但这应该可以完成工作
您可以通过+=
语法订阅事件。现在,无论何时引发事件,都会使用给定的参数激发所有订阅服务器。在本例中,PropertyChangedEventArgs
的实例。这允许您的订阅者根据给定的EventArgs
中的值做出不同的行为(您还可以将EventArgs
的空实例传递给订阅者,这意味着您的订阅者不会根据EventArgs
中的值做任何事情)
一些小改动:
- 添加了主题的枚举。在检查所选主题时添加类型安全性。这比检查硬编码字符串要好
- 添加了找不到主题集时的异常。您可以在try/catch块中相应地处理异常。同样,这比检查硬编码字符串要好
- 为appsetting键添加了常量字符串。与前两点一样,这将防止您因输入错误而出现运行时错误/为您提供一个管理值的中心位置
namespace Testing.Pages
{
public enum Themes
{
Light = 1,
Dark = 2
}
}
namespace Testing.Pages
{
public class ThemeSettingNotFoundException : Exception
{
public ThemeSettingNotFoundException() : base("error, nothing found")
{
}
}
}
namespace Testing.Pages
{
class BindingClass : INotifyPropertyChanged
{
private string _setting;
public event PropertyChangedEventHandler PropertyChanged;
public BindingClass() {
}
public BindingClass(string value) {
_setting = value;
}
public string SettingProperty
{
get { return _setting; }
set
{
if(!_setting.Equals(value)){
_setting = value;
OnPropertyChanged();
}
}
}
protected void OnPropertyChanged([CallerMemberName] string _setting = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_setting));
}
}
}
namespace Testing.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsPage : Page
{
BindingClass notifyProperty = new BindingClass();
public SettingsPage() {
this.InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
//Subscribe to the PropertyChanged event
notifyProperty.PropertyChanged += OnThemeSettingChanged;
}
private void ChangeTheme_btn_Click(object sender, RoutedEventArgs e) {
DataContext = notifyProperty;
SaveThemeSettings();
}
private void SaveThemeSettings()
{
var notifySettings = 0;
if ((bool)DarkTheme_btn.IsChecked)
notifySettings = 2;
else if ((bool)LightTheme_btn.IsChecked)
notifySettings = 1;
//Only save theme settings when a button was checked
if (notifySettings != 0)
AppSettings.saveThemeSettings((Themes)notifySettings);
}
private void OnThemeSettingChanged(object sender, PropertyChangedEventArgs args)
{
PopupText.Visibility = Visibility.Visible;
popup_animate.Begin();
}
}
}
namespace Testing.Pages
{
class AppSettings
{
private const string ThemeSettingKey = "AppThemeSetting";
public static void saveThemeSettings(Themes theme) {
ApplicationDataContainer themeSettings = ApplicationData.Current.LocalSettings;
themeSettings.Values[ThemeSettingKey] = theme.ToString();
}
public static Themes readThemeSettings() {
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
if (!localSettings.Values.ContainsKey(ThemeSettingKey))
throw new ThemeSettingNotFoundException();
var appSettingsString = localSettings.Values[ThemeSettingKey];
return (Themes)Enum.Parse(typeof(Themes), appSettingsString);
}
public static void removeLocalSettings(string settingValue) {
ApplicationData.Current.LocalSettings.Values.Remove(settingValue);
}
}
}
namespace Testing.Pages
{
公共枚举主题
{
光=1,
黑暗=2
}
}
名称空间测试.Pages
{
公共类ThemeSettingNotFoundException:异常
{
public ThemeSettingNotFoundException():base(“错误,未找到任何内容”)
{
}
}
}
名称空间测试.Pages
{
类绑定类:INotifyPropertyChanged
{
私有字符串设置;
公共事件属性更改事件处理程序属性更改;
公共绑定类(){
}
公共绑定类(字符串值){
_设置=值;
}
公共字符串设置属性
{
获取{return\u setting;}
设置
{
如果(!\u设置等于(值)){
_设置=值;
OnPropertyChanged();
}
}
}
受保护的void OnPropertyChanged([CallerMemberName]字符串_setting=”“){
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(_设置));
}
}
}
名称空间测试.Pages
{
///
///可以单独使用或在框架内导航到的空页。
///
公共密封部分类设置页面:第页
{
BindingClass notifyProperty=新的BindingClass();
公共设置页面(){
this.InitializeComponent();
NavigationCacheMode=NavigationCacheMode.Enabled;
//订阅PropertyChanged事件
notifyProperty.PropertyChanged+=OnTheSettingChanged;
}
私有void ChangeTheme\u btn\u单击(对象发送方,路由目标){
DataContext=notifyProperty;
保存当前设置();
}
私有void SaveThemeSettings()
{
var-notifySettings=0;
如果((布尔)暗模式已检查)
通知设置=2;
如果((bool)LightTheme\u btn.被选中,则为else)
通知设置=1;
//仅在选中按钮时保存主题设置
如果(notifySettings!=0)
AppSettings.saveThemeSettings((主题)notifySettings);
}
更改了设置时的私有无效(对象发送方,PropertyChangedEventArgs参数)
{
PopupText.Visibility=可见性.Visibility;
弹出动画。开始();
}
}
}
名称空间测试.Pages
{
类应用程序设置
{
private const string ThemeSettingKey=“AppThemeSetting”;
公共静态void保存主题设置(主题){
ApplicationDataContainer themeSettings=ApplicationData.Current.LocalSettings;
themeSettin
namespace Testing.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsPage : Page
{
BindingClass notifyProperty = new BindingClass();
public SettingsPage()
{
this.InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
}
private void ChangeTheme_btn_Click(object sender, RoutedEventArgs e)
{
DataContext = notifyProperty;
int notifySettings = 0;
if ((bool)DarkTheme_btn.IsChecked)
{
notifySettings = 2;
AppSettings.saveThemeSettings(notifySettings);
PopupText.Visibility = Visibility.Visible;
popup_animate.Begin();
}
else if ((bool)LightTheme_btn.IsChecked)
{
notifySettings = 1;
AppSettings.saveThemeSettings(notifySettings);
PopupText.Visibility = Visibility.Visible;
popup_animate.Begin();
}
}
}
}
namespace Testing.Pages
{
class AppSettings
{
public static void saveThemeSettings(int value)
{
ApplicationDataContainer themeSettings = ApplicationData.Current.LocalSettings;
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
themeSettings.Values["AppThemeSetting"] = value.ToString();
}
public static string readThemeSettings()
{
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
string appSettingsString = "error, nothing found";
if (localSettings.Values.ContainsKey("AppThemeSetting"))
{
appSettingsString = localSettings.Values["AppThemeSetting"]?.ToString();
}
return appSettingsString;
}
public static void removeLocalSettings(string settingValue)
{
ApplicationData.Current.LocalSettings.Values.Remove(settingValue);
}
}
}
namespace Testing.Pages
{
public enum Themes
{
Light = 1,
Dark = 2
}
}
namespace Testing.Pages
{
public class ThemeSettingNotFoundException : Exception
{
public ThemeSettingNotFoundException() : base("error, nothing found")
{
}
}
}
namespace Testing.Pages
{
class BindingClass : INotifyPropertyChanged
{
private string _setting;
public event PropertyChangedEventHandler PropertyChanged;
public BindingClass() {
}
public BindingClass(string value) {
_setting = value;
}
public string SettingProperty
{
get { return _setting; }
set
{
if(!_setting.Equals(value)){
_setting = value;
OnPropertyChanged();
}
}
}
protected void OnPropertyChanged([CallerMemberName] string _setting = "") {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_setting));
}
}
}
namespace Testing.Pages
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsPage : Page
{
BindingClass notifyProperty = new BindingClass();
public SettingsPage() {
this.InitializeComponent();
NavigationCacheMode = NavigationCacheMode.Enabled;
//Subscribe to the PropertyChanged event
notifyProperty.PropertyChanged += OnThemeSettingChanged;
}
private void ChangeTheme_btn_Click(object sender, RoutedEventArgs e) {
DataContext = notifyProperty;
SaveThemeSettings();
}
private void SaveThemeSettings()
{
var notifySettings = 0;
if ((bool)DarkTheme_btn.IsChecked)
notifySettings = 2;
else if ((bool)LightTheme_btn.IsChecked)
notifySettings = 1;
//Only save theme settings when a button was checked
if (notifySettings != 0)
AppSettings.saveThemeSettings((Themes)notifySettings);
}
private void OnThemeSettingChanged(object sender, PropertyChangedEventArgs args)
{
PopupText.Visibility = Visibility.Visible;
popup_animate.Begin();
}
}
}
namespace Testing.Pages
{
class AppSettings
{
private const string ThemeSettingKey = "AppThemeSetting";
public static void saveThemeSettings(Themes theme) {
ApplicationDataContainer themeSettings = ApplicationData.Current.LocalSettings;
themeSettings.Values[ThemeSettingKey] = theme.ToString();
}
public static Themes readThemeSettings() {
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
if (!localSettings.Values.ContainsKey(ThemeSettingKey))
throw new ThemeSettingNotFoundException();
var appSettingsString = localSettings.Values[ThemeSettingKey];
return (Themes)Enum.Parse(typeof(Themes), appSettingsString);
}
public static void removeLocalSettings(string settingValue) {
ApplicationData.Current.LocalSettings.Values.Remove(settingValue);
}
}
}
public string SettingProperty
{
get { return _setting; }
set
{
if(_setting != value) // Or String.Equals(_setting, value, ...)
{
_setting = value;
OnPropertyChanged(); // Invoke using no argument.
}
}
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}