[英]INotifyPropertyChanged-Feature on Auto-Properties
[英]INotifyPropertyChanged and Auto-Properties
有沒有辦法將INotifyPropertyChanged
與自動屬性一起使用? 也許是一個屬性或其他東西,對我來說並不明顯。
public string Demo{
get;set;
}
對我來說,自動屬性將是一件非常實用的事情,但幾乎總是,如果屬性值已更改並且沒有執行此操作的機制,則幾乎總是我必須引發PropertyChanged
事件,自動屬性對我來說毫無用處。
在 .NET 4.5 及更高版本中,它可以縮短一些:
private int unitsInStock;
public int UnitsInStock
{
get { return unitsInStock; }
set { SetProperty(ref unitsInStock, value);}
}
這是你必須自己編碼的東西。 你能得到的最接近的是代碼項目上的這個實現,它使用自定義屬性和面向方面的方法來提供以下語法:
[NotifyPropertyChanged]
public class AutoWiredSource
{
public double MyProperty { get; set; }
}
有人曾經在 Microsoft Connect 上提議對 C# 規范進行更改來實現這一點:
class Person : INotifyPropertyChanged
{
// "notify" is a context keyword, same as "get" and "set"
public string Name { get; set; notify; }
}
但該提案現已結束。
沒有內置機制可以做到這一點。 像PostSharp這樣的東西可能會為你添加這樣的東西(或者 Mark Gravell 的HyperDescriptor ,如果你只是對讓這個數據綁定感知感興趣)。
我首先嘗試使用其他方法:
這些方法有效,但是我仍然不得不混淆模型中所有屬性的訪問器方法,或者使用dynamic
對象在編碼時殺死您的自動完成。 還值得一提的是,不幸的是,WinForms 不支持綁定到動態對象。
最終我遇到了ReactiveUI.Fody 。 這是一個使用 Fody 和 ReactiveUI 的簡單易用的解決方案。 我成功地在我的 WPF 項目中使用了它。
它在編譯時編入所需的樣板代碼RaisePropertyChanges
和ObservableAsPropertyHelper
。
https://github.com/kswoll/ReactiveUI.Fody
我使用 NuGet 在我的項目中安裝了以下包:
<packages>
<package id="Fody" version="2.0.7" targetFramework="net452" developmentDependency="true" />
<package id="reactiveui" version="7.4.0" targetFramework="net452" />
<package id="ReactiveUI.Fody" version="2.2.11" targetFramework="net452" />
<package id="reactiveui-core" version="7.4.0" targetFramework="net452" />
<package id="Rx-Core" version="2.2.5" targetFramework="net452" />
<package id="Rx-Interfaces" version="2.2.5" targetFramework="net452" />
<package id="Rx-Linq" version="2.2.5" targetFramework="net452" />
<package id="Rx-Main" version="2.2.5" targetFramework="net452" />
<package id="Rx-PlatformServices" version="2.2.5" targetFramework="net452" />
<package id="Rx-XAML" version="2.2.5" targetFramework="net452" />
<package id="Splat" version="1.6.0" targetFramework="net452" />
</packages>
您需要在項目的頂層創建一個 FodyWeavers.xml 文件,如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<Weavers>
<ReactiveUI/>
</Weavers>
您只需將 Model 類設置為繼承ReactiveObject
並在要通知更改的任何屬性上方添加[Reactive]
屬性。
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
namespace name.domain.some{
class SomeClass : ReactiveObject {
[Reactive]
public string SomeProperty { get; set; }
}
}
大功告成! 重建項目並檢查 Visual Studio 中的輸出窗口。 在 Fody 處理帶注釋的模型類並注入適當的樣板代碼時,您應該會看到一些從 Fody 輸出的行。 它應該是這樣的:
更多有用的信息可以在這里找到。
INotifyPropertyChanged
和 DependencyProperties 確實讓屬性變得不那么有趣。 我發現的最佳解決方案是好的片段。 例如Silverlight contrib項目中的那些
crea7or 的有用答案,最終在我的最新項目中使用了它。 改進它的一種方法是通過這種方式重寫 SetProperty:
protected bool SetProperty<T>(ref T storage, T value, string[] dependentPropertyNames = null, [CallerMemberName] string propertyName = null)
{
if (Equals(storage, value))
{
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
if(dependentPropertyNames != null)
{
foreach(var dependentPropertyName in dependentPropertyNames)
{
OnPropertyChanged(dependentPropertyName);
}
}
return true;
}
它現在允許傳入依賴屬性名稱,允許視圖知道依賴屬性值已更改,即使它不是直接設置的,而是設置了其他屬性的結果。
用法:
private string firstName;
public string FirstName
{
get { return firstName; }
set { SetProperty(ref firstName, value, new[] { "FullName" }); }
}
private string lastName;
public string LastName
{
get { return lastName; }
set { SetProperty(ref lastName, value, new[] { "FullName" }); }
}
public string FullName
{
get { return $"{FirstName} {LastName}"; }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.