附加属性事件模式






4.33/5 (5投票s)
通过附加属性和 IEventAggregator 发布事件的模式
引言
在我们的项目中,我们使用了Composite WPF模型,并且需要一种从视图(XAML代码)发布事件的方式,而无需创建任何代码隐藏文件,并且没有任何依赖关系。为了发布和订阅事件,我们已经使用了IEventAggregator
,但仍然需要在代码隐藏文件中编写一些代码来发布事件。
因此,我们想出了我们称之为“AttachedPropertyEvent
”的东西。
关于示例
在这个示例中,我将实现datagrid
上的SelectedItemsChanged
。datagrid
位于一个视图中,我希望在某个viewmodel
中订阅此事件。
实现
首先,我们在我们的Infrastructure项目中,Events命名空间中创建一个带有get
和set
方法的AttachedProperty
,以及一个用于执行某些逻辑的回调函数。
public static class SelectedItemsChangedApe
{
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems",
typeof (object),
typeof (SelectedItemsChangedApe),
new PropertyMetadata(RaiseEventCallback));
public static object GetSelectedItems(DependencyObject obj)
{
return obj.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject obj, object value)
{
obj.SetValue(SelectedItemsProperty, value);
}
private static void RaiseEventCallback
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// Implement logic here
}
}
接下来,我们需要在我们的视图(XAML)中实现附加属性。我们使用Xceed DataGridControl
作为我们的datagrid
。
<xceed:DataGridControl
x:Name="gridControl"
ItemsSource="Some item source"
Events:SelectedItemsChangedApe.SelectedItems=
"{Binding RelativeSource={RelativeSource Self}, Path=SelectedItem}" />
现在我们已经有一个附加属性,实际上并没有做太多事情。我们现在想要做的是,每次选择的项目发生变化时就发布一个事件。为了实现这一点,我们使用IEventAggregator
。所以回到我们的Infrastructure项目,我们首先通过从CompositePresentationEvent
(Microsoft.Practices.Composite.Presentation.Events
)派生来创建我们自己的事件。
public class SelectedItemsChangedEvent : CompositePresentationEvent<IList<object>> { }
因此,有了我们的组合演示事件,我们可以回到我们的附加属性并实现回调方法中的逻辑。我们想要做的是发布SelectedItemsChangedEvent
。首先,我们使用ServiceLocator
获取我们的IEventAggregator
,并将事件发布到事件聚合器。
private static void RaiseEventCallback
(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
IEventAggregator eventAggregator =
ServiceLocator.Current.GetInstance<IEventAggregator>();
eventAggregator.GetEvent<SelectedItemsChangedEvent>().Publish
(e.NewValue as IList<object>);
}
现在我们的事件已经发布,我们只需要订阅它。在这个例子中,我有一个viewmodel
,我在构造函数中订阅该事件。
public SomeViewModel()
{
IEventAggregator eventAggregator =
ServiceLocator.Current.GetInstance<IEventAggregator>();
eventAggregator.GetEvent<SelectedItemsChangedEvent>().Subscribe
(OnSelectedItemsChanged);
}
private void OnSelectedItemsChanged(IList<object> obj)
{
// Implement logic here
}
就是这样。
关注点
这是我们使用此模式的第一个实现。目前,您需要为要发布的每个事件创建一个附加属性和一个事件。我们目前正在努力使其通用化。
历史
- 2009年7月2日 - 文章上传