NotifyPropertyChanged 未触发事件 [PostSharp]
NotifyPropertyChanged not firing event [PostSharp]
我是 PostSharp 的新手(刚拿到许可证),我一直在尝试在我的应用程序中使用它。我有一个设置 class 如下:
[NotifyPropertyChanged]
public class Consts
{
public string test2 {get; set;} = "foobar";
public string test
{
get { return GetValue("test"); }
set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); }
}
[Pure]
public static string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)];
[Pure]
private static void UpdateSetting(string key, string value)
{
var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cfg.AppSettings.Settings[key].Value = value;
cfg.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
}
然后在我的订阅者 class 上:
var cst = new Consts();
Post.Cast<Consts, INotifyPropertyChanged>(cst).PropertyChanged +=
(o, args) => Debug.Write("PropertyChanged fired");
cst.test = "test test"; // Gives no result
cst.test2 = "test test"; // Event firing correctly
当我在我的 getter 和 setter 中使用方法时,事件没有触发,虽然标记为纯方法,但是当它是一个简单的 属性.
时工作正常
我花了最后一天时间搜索 Google 寻找答案,但没有成功;没有线程可以解决我的问题。
我错过了什么?
[NotifyPropertyChanged]
方面检测 class 字段的更改,然后根据检测到的依赖项触发适当的事件(属性 值取决于该特定字段)。
在您的情况下,这正是 test2
属性 所做的,以及 属性.
方面为何有效
另一方面test
属性不能自动工作。 属性 的值取决于 ConfigurationManager.AppSettings.Item
。第一个问题是 AppSettings
是静态的 属性,即不可能检测到它的变化。如果假设它永远不会改变,那么第二个问题是 NameValueCollection
没有实现 INotifyPropertyChanged
,这意味着没有办法知道这个值实际上改变了。
您没有收到任何警告,因为您已将这两种方法都标记为 Pure
,它们不是通常意义上的词。 GetValue
使用全局可变状态。 SetValue
更改全局可变状态。
由于无法挂接到 AppSettings
以接收对集合的更改,因此您需要在设置 属性 时发出更改通知。这可以通过调用 NotifyPropertyChangedServices.SignalPropertyChanged
方法来完成。您的代码将如下所示:
[NotifyPropertyChanged]
public class Consts
{
public string test2 { get; set; } = "foobar";
public string test
{
get { return GetValue("test"); }
set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); }
}
[SafeForDependencyAnalysis]
public string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)];
private void UpdateSetting(string key, string value)
{
var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cfg.AppSettings.Settings[key].Value = value;
cfg.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
NotifyPropertyChangedServices.SignalPropertyChanged(this, key);
}
}
请注意,如果存在 Consts
class 的多个实例,它们将不会共享更改,因此无法通过 ConfigurationManaged
传递该信息。
我是 PostSharp 的新手(刚拿到许可证),我一直在尝试在我的应用程序中使用它。我有一个设置 class 如下:
[NotifyPropertyChanged]
public class Consts
{
public string test2 {get; set;} = "foobar";
public string test
{
get { return GetValue("test"); }
set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); }
}
[Pure]
public static string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)];
[Pure]
private static void UpdateSetting(string key, string value)
{
var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cfg.AppSettings.Settings[key].Value = value;
cfg.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
}
}
然后在我的订阅者 class 上:
var cst = new Consts();
Post.Cast<Consts, INotifyPropertyChanged>(cst).PropertyChanged +=
(o, args) => Debug.Write("PropertyChanged fired");
cst.test = "test test"; // Gives no result
cst.test2 = "test test"; // Event firing correctly
当我在我的 getter 和 setter 中使用方法时,事件没有触发,虽然标记为纯方法,但是当它是一个简单的 属性.
时工作正常我花了最后一天时间搜索 Google 寻找答案,但没有成功;没有线程可以解决我的问题。
我错过了什么?
[NotifyPropertyChanged]
方面检测 class 字段的更改,然后根据检测到的依赖项触发适当的事件(属性 值取决于该特定字段)。
在您的情况下,这正是 test2
属性 所做的,以及 属性.
另一方面test
属性不能自动工作。 属性 的值取决于 ConfigurationManager.AppSettings.Item
。第一个问题是 AppSettings
是静态的 属性,即不可能检测到它的变化。如果假设它永远不会改变,那么第二个问题是 NameValueCollection
没有实现 INotifyPropertyChanged
,这意味着没有办法知道这个值实际上改变了。
您没有收到任何警告,因为您已将这两种方法都标记为 Pure
,它们不是通常意义上的词。 GetValue
使用全局可变状态。 SetValue
更改全局可变状态。
由于无法挂接到 AppSettings
以接收对集合的更改,因此您需要在设置 属性 时发出更改通知。这可以通过调用 NotifyPropertyChangedServices.SignalPropertyChanged
方法来完成。您的代码将如下所示:
[NotifyPropertyChanged]
public class Consts
{
public string test2 { get; set; } = "foobar";
public string test
{
get { return GetValue("test"); }
set { UpdateSetting(nameof(test), value.ToString(CultureInfo.InvariantCulture)); }
}
[SafeForDependencyAnalysis]
public string GetValue(string s) => ConfigurationManager.AppSettings[nameof(s)];
private void UpdateSetting(string key, string value)
{
var cfg = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
cfg.AppSettings.Settings[key].Value = value;
cfg.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("appSettings");
NotifyPropertyChangedServices.SignalPropertyChanged(this, key);
}
}
请注意,如果存在 Consts
class 的多个实例,它们将不会共享更改,因此无法通过 ConfigurationManaged
传递该信息。