我知道MVVM大量使用INotifyPropertyChanged,但我從未見過INotifyPropertyChanging的任何用法。任何理由?爲什麼沒有人使用INotifyPropertyChanging?
如果我想用這個,這將是該融入我的MVVM框架的好辦法?我知道你不應該在ViewModel上使用MessageBox
,因爲那樣你就無法對它進行單元測試。那麼如何才能拋出警報,然後繼續使用PropertyChange(如果適用)?
我知道MVVM大量使用INotifyPropertyChanged,但我從未見過INotifyPropertyChanging的任何用法。任何理由?爲什麼沒有人使用INotifyPropertyChanging?
如果我想用這個,這將是該融入我的MVVM框架的好辦法?我知道你不應該在ViewModel上使用MessageBox
,因爲那樣你就無法對它進行單元測試。那麼如何才能拋出警報,然後繼續使用PropertyChange(如果適用)?
需要記住的事項INotifyPropertyChanging
是你不能停止從發生的變化。這隻允許您記錄發生的變化。
我用它在我的更改跟蹤的框架,但它不是停止變化的適當方法。
你可以使用自定義接口/事件對延長您的ViewModelBase
:
delegate void AcceptPendingChangeHandler(
object sender,
AcceptPendingChangeEventArgs e);
interface IAcceptPendingChange
{
AcceptPendingChangeHandler PendingChange;
}
class AcceptPendingChangeEventArgs : EventArgs
{
public string PropertyName { get; private set; }
public object NewValue { get; private set; }
public bool CancelPendingChange { get; set; }
// flesh this puppy out
}
class ViewModelBase : IAcceptPendingChange, ...
{
protected virtual bool RaiseAcceptPendingChange(
string propertyName,
object newValue)
{
var e = new AcceptPendingChangeEventArgs(propertyName, newValue)
var handler = this.PendingChange;
if (null != handler)
{
handler(this, e);
}
return !e.CancelPendingChange;
}
}
此時你需要按照慣例將它添加到您的視圖模型:
class SomeViewModel : ViewModelBase
{
public string Foo
{
get { return this.foo; }
set
{
if (this.RaiseAcceptPendingChange("Foo", value))
{
this.RaiseNotifyPropertyChanging("Foo");
this.foo = value;
this.RaiseNotifyPropretyChanged("Foo");
}
}
}
}
要回答第二個問題,你總是可以使用依賴注入模式,讓您的虛擬機依賴的接口(INotifier?)上,並通過一個具體的實施會彈出消息框。這使單元測試性保持不變。
編輯: 第一個問題可能是這麼過於主觀。界面的意圖很明確,但何時使用它將用於非常具體的用例。依賴屬性引發了類似的情況,在應用它之前檢查新值是有效的,但如果使用簡單屬性,則可以更簡單地將此檢查放入設置器中。如果不同的組件需要檢查有效性,那麼如果該組件自己(在驗證新值之後)進行更改,或者被顯式調用以驗證由進行更改的組件進行的更改,則通常會更簡單。
您需要INotifyPropertyChanged例如,如果你想知道什麼時候任何變量將被改變,因爲你可以使用PropertyChangedEventHandler。 通過這種方式,您可以在運行程序時重新加載gui,如果有任何依賴屬性綁定在任何gui元素上。
對於最後一個問題,我想你可以寫一個日誌文件與你定義的消息,如果你想顯示給用戶的任何警報,您可以使用類似的錯誤總結或提示控件。但是,如果您只需要進行測試,則可以使用try和catch塊保留警報。
OP詢問'INotifyPropertyChanging'接口,而不是'INotifyPropertyChanged' –
忽略錯誤接口的無辜錯誤,在本場景中鑽入日誌文件並嘗試/捕獲不存在的屬性驗證異常不是很好的建議。 – JRoughan
INotifyPropertyChanging在屬性更改之前被調用。重要原因?所以外部事件處理程序可以拋出異常並阻止更改。你爲什麼要這麼做?有一天它可能是你在別人的代碼庫中的一個錯誤的唯一解決方法,所以不要那麼快地刪除逃生艙口。
在事件處理程序中拋出一個異常來結束事件執行時,firer會引起我的巨大代碼嗅覺,包括執行此操作的選項*以防萬一使我感覺更糟。 –
INotifyPropertyChanging是使用LINQ到使用SQL優化。當一個對象實現這個接口時,它使用改變事件作爲緩存屬性的舊值的信號。如果對象沒有實現這個接口,那麼它總是會緩存屬性值,從而增加內存使用量。 有關更多詳細信息,請參閱How does INotifyPropertyChanging interface helps limit memory consumption。
你想在這裏實現什麼?知道什麼時候房產是*關於*改變的用例是什麼? – ChrisF
驗證用戶「你確定嗎?」對於某些更改......我們希望確保管理員意味着更改用戶的用戶名/登錄名,並且他們不會意外更新該字段。 – michael