[英]Events, methods using these events and inheritance
我正在創建使用WPF開發的軟件的程序端體系結構,並且將該體系結構設計為符合MVVM模式。
出於許多原因(設計,一致性,可重用性,可維護性,可伸縮性等),我創建了實現接口INotifyPropertyChanged
和其他方法的BaseViewModel
類:
public class BaseViewModel: INotifyPropertyChanged
{
private PropertyChangedEventHandler property_changed;
public event PropertyChangedEventHandler PropertyChanged
{
add { property_changed += value; }
remove { property_changed -= value; }
}
//Here several methods using PropertyChanged and easing the usage of ViewModels
public BaseViewModel() { }
}
上面定義的類BaseViewModel
用作應用程序的所有其他ViewModel
的基類(或者至少是這樣),例如:
public class SampleViewModel : BaseViewModel
{
//private PropertyChangedEventHandler property_changed;
//public event PropertyChangedEventHandler PropertyChanged
//{
// add { property_changed += value; }
// remove { property_changed -= value; }
//}
public String Name
{
get { return name; }
set
{
if(value != name)
{
name = value;
var handler = PropertyChanged;
if(handler != null)
{
handler(this, new PropertyChangedEventArgs("Name"));
}
}
}
}
private String name = "";
public SampleViewModel ()
: base() { }
}
我使用類SampleViewModel
作為SampleViewModel
的DataContext
,它SampleUserControl
了DependencyProperty
:
public partial class SampleUserControl : UserControl
{
#region ViewModel
public SampleViewModel ViewModel
{
get { return view_model; }
}
private SampleViewModel view_model = new SampleViewModel();
#endregion
#region DependencyProperty
public String Text
{
get { return (String)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(String), typeof(SampleUserControl),
new FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(TextPropertyChangedCallback)));
private static void TextPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
SampleUserControl sender = d as SampleUserControl;
if (sender != null)
{
sender.ViewModel.Name = (String)e.NewValue;
}
}
#endregion
public SampleUserControl()
{
InitializeComponent();
LayoutRoot.DataContext = ViewModel;
ViewModel.PropertyChanged += new PropertyChangedEventHandler(ViewModel_PropertyChanged);
}
void ViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
SampleViewModel viewmodel = sender as SampleViewModel;
if (viewmodel != null)
{
switch (e.PropertyName)
{
case "Name":
SetValue(TextProperty, viewmodel.Name);
break;
default:
break;
}
}
}
}
總而言之,與SampleUserControl
有關的數據包含在三個位置: SampleViewModel
的實例,位於TextProperty
和位於SampleUserControl
的xaml部分中的TextBox
屬性Text
中(此屬性Text
是通過Binding
與字段Name
雙向Binding
的)的ViewModel
)。
為了同步這三個值,我添加了TextPropertyChangedCallback
和ViewModel_PropertyChanged
方法,它們更新了需要更新的字段。
上面的代碼可以正常工作,並且上面提到的三個位置都保持最新,事件發生等,當使用SampleUsercontrol
進行數據綁定時,一切都很好。
但是SampleViewModel
會觸發事件BaseViewModel.PropertyChanged
,並且由於打算廣泛使用BaseViewModel
,因此我希望每個ViewModel
都有自己的事件PropertyChanged
,至少是為了避免事件重疊。
所以我取消的代碼SampleViewModel
從而重新定義了事件PropertyChanged
,但它打破了該領域之間的同步Name
的實例SampleViewModel
和財產TextProperty
的SampleUserControl
。
我在構思方面犯了一些錯誤嗎? 您對我有什么指導嗎? 為每個繼承自BaseViewModel
ViewModel定義不同事件PropertyChanged
的最佳經濟方法是什么,同時仍使用該基類中定義的通用方法(此類方法使用PropertyChanged
)? (我想避免要粘貼大量代碼。)
我知道更多的是關於優化的,但是這種優化可以在速度較慢的軟件和速度較快的軟件之間產生區別。 我處於代碼分解的階段,因此我喜歡形狀優美,優雅且分解的代碼。
一天結束了,我可能會錯過一些明顯的解決方案。
預先感謝您提供任何線索,朱利安
TL; DR:基本上,我會仔細檢查您是否在該用戶控件上正確執行了DC / DP,並拋出了PropertyChanged
多個定義的任何概念
詳細:
PropertyChanged
,這很棒。 沒有理由在其他任何地方重新定義它 。 確實,您只是在通過這樣做自找麻煩。 handler
。 減少復制粘貼。 TextPropertyChanged
的事實在這里是一個巨大的 TextPropertyChanged
信號。 與真正的問題有關,您可能正在濫用依賴項屬性。 DP用於允許父控件綁定到用戶控件的屬性。 通常,您不會將它們與控件內部的數據上下文一起使用,因為如您所見,保持它們同步是一場噩夢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.