扩展MVVM的现有控件

时间:2011-04-05 07:19:42

标签: c# .net data-binding mvvm dependency-properties

我想扩展一个名为PivotViewer的现有微软控件。

此控件具有我想要向ViewModel公开的现有属性。

public ICollection<string> InScopeItemIds { get; }

我创建了一个名为CustomPivotViewer的继承类,我想创建一个可以绑定到的依赖项属性,它将公开基类中InScopeItemIds中保存的值。

我在阅读有关DependencyPropertys的过程中花了很多时间,我觉得很沮丧。

这甚至可能吗?

2 个答案:

答案 0 :(得分:0)

修改

我意识到误解,这是一个新版本(在原始问题的背景下):

因此,您可以使用绑定所需的属性,并考虑以下情况:

  • 由于此属性是只读的,因此您无法将其用于双向绑定。
  • 就包含类型未实现INotifyPropertyChanged而言,用于显示数据的目标控件将不会收到有关属性值更改的通知。
  • 只要此属性值返回的内容未实现INotifyCollectionChanged(一个示例是ObservableCollection&lt; T&gt;),对用于显示它的目标控件的集合更改不会受到影响。

答案 1 :(得分:0)

您只需要一个DependencyProperty 是可绑定的,这意味着:如果您希望在控件中拥有MyBindableProperty属性,则您希望能够做到:

MyBindableProperty={Binding SomeProperty}

但是,如果您希望其他DependencyProperties 绑定到,则任何属性(DependencyProperty或普通属性)都可以使用。

我不确定你真正需要什么,也许你可以澄清更多,但如果这是你想要实现的第一个场景,你可以按如下方式进行:

  • 创建DependencyProperty,我们称之为BindableInScopeItemIds,如下所示:

    /// <summary>
    /// BindableInScopeItemIds Dependency Property
    /// </summary>
    public static readonly DependencyProperty BindableInScopeItemIdsProperty =
        DependencyProperty.Register("BindableInScopeItemIds", typeof(ICollection<string>), typeof(CustomPivotViewer),
            new PropertyMetadata(null,
                new PropertyChangedCallback(OnBindableInScopeItemIdsChanged)));
    
    /// <summary>
    /// Gets or sets the BindableInScopeItemIds property. This dependency property 
    /// indicates ....
    /// </summary>
    public ICollection<string> BindableInScopeItemIds
    {
        get { return (ICollection<string>)GetValue(BindableInScopeItemIdsProperty); }
        set { SetValue(BindableInScopeItemIdsProperty, value); }
    }
    
    /// <summary>
    /// Handles changes to the BindableInScopeItemIds property.
    /// </summary>
    private static void OnBindableInScopeItemIdsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var target = (CustomPivotViewer)d;
        ICollection<string> oldBindableInScopeItemIds = (ICollection<string>)e.OldValue;
        ICollection<string> newBindableInScopeItemIds = target.BindableInScopeItemIds;
        target.OnBindableInScopeItemIdsChanged(oldBindableInScopeItemIds, newBindableInScopeItemIds);
    }
    
    /// <summary>
    /// Provides derived classes an opportunity to handle changes to the BindableInScopeItemIds property.
    /// </summary>
    protected virtual void OnBindableInScopeItemIdsChanged(ICollection<string> oldBindableInScopeItemIds, ICollection<string> newBindableInScopeItemIds)
    {
    }
    
  • OnBindableInScopeItemIdsChanged
  • ,您可以更新内部集合(InScopeItemIds

请记住,您要公开的属性是只读(它没有“setter”),因此您可能需要更新它:

protected virtual void OnBindableInScopeItemIdsChanged(ICollection<string> oldBindableInScopeItemIds, ICollection<string> newBindableInScopeItemIds)
{
    InScopeItemIds.Clear();
    foreach (var itemId in newBindableInScopeItemIds)
    {
        InScopeItemIds.Add(itemId);
    }
}

希望这会有所帮助:)