[英]Events, methods using these events and inheritance
I am creating the program-side architecture of a software developped in WPF, I designed the architecture as being compliant with the MVVM pattern. 我正在创建使用WPF开发的软件的程序端体系结构,并且将该体系结构设计为符合MVVM模式。
For many sakes (design, coherence, reusability, maintainability, scalability, etc) I created the class BaseViewModel
implementing the interface INotifyPropertyChanged
and some other methods: 出于许多原因(设计,一致性,可重用性,可维护性,可伸缩性等),我创建了实现接口
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() { }
}
The above-defined class BaseViewModel
is used as a base class for all the other ViewModel
s of the application (or, at least, is meant to be so), for example: 上面定义的类
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() { }
}
I use the class SampleViewModel
as the DataContext
of SampleUserControl
which bares a DependencyProperty
: 我使用类
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;
}
}
}
}
To sum up, the data relative to SampleUserControl
are contained at three locations : the instance of SampleViewModel
, within TextProperty
and within the property Text
of a TextBox
in the xaml part of SampleUserControl
(this property Text
is twoway-bound through Binding
with the field Name
of ViewModel
). 总而言之,与
SampleUserControl
有关的数据包含在三个位置: SampleViewModel
的实例,位于TextProperty
和位于SampleUserControl
的xaml部分中的TextBox
属性Text
中(此属性Text
是通过Binding
与字段Name
双向Binding
的)的ViewModel
)。
To synchronize the three values, I added the methods TextPropertyChangedCallback
and ViewModel_PropertyChanged
which update the fields which need to be updated. 为了同步这三个值,我添加了
TextPropertyChangedCallback
和ViewModel_PropertyChanged
方法,它们更新了需要更新的字段。
The above code works and the three above-mentionned locations are kept up-to-date, events fire and so on, things are fine when SampleUsercontrol
is consumed with data-binding. 上面的代码可以正常工作,并且上面提到的三个位置都保持最新,事件发生等,当使用
SampleUsercontrol
进行数据绑定时,一切都很好。
But SampleViewModel
fires the event BaseViewModel.PropertyChanged
, and since BaseViewModel
is meant to be extensively used, I would like each ViewModel
to have its own event PropertyChanged
, at least in order to avoid overlapping events. 但是
SampleViewModel
会触发事件BaseViewModel.PropertyChanged
,并且由于打算广泛使用BaseViewModel
,因此我希望每个ViewModel
都有自己的事件PropertyChanged
,至少是为了避免事件重叠。
So I uncomment the code of SampleViewModel
thus redefining the event PropertyChanged
but it breaks down the synchronization between the field Name
of the instance of SampleViewModel
and the property TextProperty
of SampleUserControl
. 所以我取消的代码
SampleViewModel
从而重新定义了事件PropertyChanged
,但它打破了该领域之间的同步Name
的实例SampleViewModel
和财产TextProperty
的SampleUserControl
。
Am I making some mistakes on the conception side? 我在构思方面犯了一些错误吗? Do you have any guidance for me?
您对我有什么指导吗? What is the best economic way of defining a different event
PropertyChanged
for each ViewModel inheriting from BaseViewModel
while still using the general-purpose methods defined within that base class (such methods use PropertyChanged
)? 为每个继承自
BaseViewModel
ViewModel定义不同事件PropertyChanged
的最佳经济方法是什么,同时仍使用该基类中定义的通用方法(此类方法使用PropertyChanged
)? (I would like to avoid having heavy pieces of code to copy-paste.) (我想避免要粘贴大量代码。)
I know that it is more about optimization, but such optimizations can make a difference between a slow software and a fast one. 我知道更多的是关于优化的,但是这种优化可以在速度较慢的软件和速度较快的软件之间产生区别。 I am at the stage of code-factoring, so I fancy nicely-shaped, elegant and factorized code.
我处于代码分解的阶段,因此我喜欢形状优美,优雅且分解的代码。
End of the day happening, I may miss some obvious solutions. 一天结束了,我可能会错过一些明显的解决方案。
Thanks in advance for any clue, Julien 预先感谢您提供任何线索,朱利安
TL;DR: Basically, I would double-check that you are doing your DC/DP on that user control correctly, and toss out any concept of multiple definitions of PropertyChanged
TL; DR:基本上,我会仔细检查您是否在该用户控件上正确执行了DC / DP,并抛出了
PropertyChanged
多个定义的任何概念
In detail: 详细:
PropertyChanged
in the base class, which is great. PropertyChanged
,这很棒。 There is no reason to ever redefine it anywhere else . handler
bit in the settter. handler
。 Insta-reduction of copy paste. TextPropertyChanged
is a huge red flag here. TextPropertyChanged
的事实在这里是一个巨大的 TextPropertyChanged
信号。 Which relates to the real problem, that you are probably abusing your dependency property.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.