约定难题:
为简单起见,假设我有一个名为 FruitView 的视图,其标签上写着“选择一种水果:”,并在 ListBox 中选择了苹果、橙子、梨等。
每个项目都是一个类的实例(Apple.cs、Orange.cs、Pear.cs 等)。
ViewModel 使用绑定属性跟踪选定的水果:
public Fruit CurrentFruit { get; set; }
“水果”本身就是苹果、橙子、梨子等每一个派生出来的接口。
现在,另一个步骤,Apple、Orange、Pear 等 Apple.cs 中的每一个都依赖于名为 AppleManager、OrangeManager、PearManager 等的静态类,它们具有方法和事件。这些管理器有很大不同,并且不是从任何公共基础或接口派生的。
例如,AppleManager 可能有:
public delegate void ColorChangedEventHandler(string color);
public static event ColorChangedEventHandler ColorChanged;
private void RaiseColorChanged(string color)
{
if (ColorChanged != null)
{
ColorChanged(color);
}
}
当在视图中选择“苹果”时,视图的其余按钮、图像等需要对源自 AppleManager 的事件做出反应;when "orange" is selected, the view needs to react to events in OrangeManager.
那么,问题是,将 View 的反应方法连接到 ViewModel 中 CurrentFruit 的管理器的正确途径是什么?
我的意思是,有可能去:
private void FruitListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// pseudocode: if apple selected, AppleManager.ColorChanged += new ColorChangedEventHandler(CurrentFruit_ColorChanged);
}
private void CurrentFruit_ColorChanged(string color)
{
FruitColorTextBox.Text = color;
}
这是不可接受的原因是因为它破坏了设计模式,并且意味着我需要处理每种水果。
实际上,我有很多医疗设备,而不是水果选项,我想将接口用作接口,而不是添加额外的逻辑。
我当前的解决方案是将事件添加到接口 VCONF,如下所示:
public interface VCONF
{
public static event CallIncomingEventHandler CallIncoming;
public static event EventArgs CallStarted;
public static event EventArgs CallEnded;
}
现在 VCONF1、VCONF2、VCONF3 等都是从 VCONF 派生的,它们实现了这些事件,并有方法来引发它们。
这意味着我必须在每个 VCONF1 等中编写相同的事件行,但这与让多个类继承 INotifyPropertyChanged 相同——这就是我以这种方式设置它的原因)。这也意味着在 VCONF1Manager 中编写相同的事件和引发方法——引发事件链,上层引发事件,上层引发事件,等等,直到 View 可以对其做出反应。VCONF1Manager.CallIncoming -> VCONF1.CallIncoming -> 查看反应
VCONF1订阅VCONF1Manager中的事件,VCONF2订阅VCONF2Manager中的事件等。
其他 VCONF?甚至可能没有经理,只是有自己的方式来确定何时引发这些事件。
View 在被选中时订阅当前 VCONF 的事件:
private void VCONF_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
(this.DataContext as VCONFViewModel).CurrentVCONF = (sender as ListBox).SelectedValue as VCONF;
(((sender as ListBox).SelectedValue as VCONF).Device as VCONF).CallIncoming += new CallIncomingEventHandler(CurrentVCONF_CallIncoming);
// same for other events
...
}
所以,我在这里真正要问的是,通过层/抽象链接事件的首选/传统方式是什么?
我正在做的工作,但我不禁觉得连续加倍和链接事件并不是最好的方法。
提前致谢。