65.9K
CodeProject 正在变化。 阅读更多。
Home

附加属性事件模式

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.33/5 (5投票s)

2009 年 7 月 2 日

CPOL

2分钟阅读

viewsIcon

14668

通过附加属性和 IEventAggregator 发布事件的模式

引言

在我们的项目中,我们使用了Composite WPF模型,并且需要一种从视图(XAML代码)发布事件的方式,而无需创建任何代码隐藏文件,并且没有任何依赖关系。为了发布和订阅事件,我们已经使用了IEventAggregator,但仍然需要在代码隐藏文件中编写一些代码来发布事件。

因此,我们想出了我们称之为“AttachedPropertyEvent”的东西。

关于示例

在这个示例中,我将实现datagrid上的SelectedItemsChangeddatagrid 位于一个视图中,我希望在某个viewmodel中订阅此事件。

实现

首先,我们在我们的Infrastructure项目中,Events命名空间中创建一个带有getset方法的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项目,我们首先通过从CompositePresentationEventMicrosoft.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日 - 文章上传
© . All rights reserved.