C# 无法理解INotifyPropertyChanged的实现

C# 无法理解INotifyPropertyChanged的实现,c#,xaml,uwp,C#,Xaml,Uwp,我只是C#的新手,我在MSDN博客上读到了关于INotifyPropertyChanged事件处理程序的INotifyPropertyChanged事件处理程序,并在这里的“stackoverflow”上搜索。但我并不真正理解如何在代码中实现它,以及如何将事件和属性绑定在一起。 我已经用INotifyPropertyChanged创建了一个BindingClass,代码是: namespace Testing.Pages { class BindingClass : INotifyPrope

我只是C#的新手,我在MSDN博客上读到了关于INotifyPropertyChanged事件处理程序的
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));
    }