【问题标题】:Extending an existing control for MVVM扩展 MVVM 的现有控件
【发布时间】:2011-07-29 17:48:22
【问题描述】:

我正在尝试扩展一个名为 PivotViewer 的现有 Microsoft 控件。

此控件有一个我想公开给我的 ViewModel 的现有属性。

public ICollection<string> InScopeItemIds { get; }

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

我花了很长时间阅读有关 DependencyPropertys 的内容,现在变得非常沮丧。

这可能吗?

【问题讨论】:

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


    【解决方案1】:

    编辑

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

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

    • 由于此属性是只读的,您将无法将其用于双向绑定。
    • 只要包含类型没有实现 INotifyPropertyChanged,用于显示数据的目标控件将不会收到有关属性值更改的通知。
    • 只要此属性值返回的没有实现 INotifyCollectionChanged(例如 ObservableCollection),对集合的更改不会影响用于显示它的目标控件。

    【讨论】:

    • 问题中的属性没有设置器。
    • 这意味着使用某些您无法更改的特定于类的内部代码更改值,对吗?在这种情况下,当属性更改时,您将看不到目标控件上的更改。
    • @Tengiz,提醒我,设置了一种方式绑定但没有获取,对吗?
    • 一种方式绑定意味着源属性显示在目标控件上。因此,您可以显示它,但不能从目标控件更改它。为简单起见:目标可以是文本框,源可以是您的类。同样,如果类没有实现 INOtifyPropertyChanged,那么当类值发生变化时,控件将不会更新其值。
    • 可以拥有带有 any 属性的双向 DataBinding,该属性both 是一个 setter 和一个 getter。 DependencyProperty 是当你想让属性 itself 成为 Bindable 时(见我的回复)
    【解决方案2】:

    您只需要一个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);
        }
    }
    

    希望这会有所帮助:)

    【讨论】:

    • 我认为使用 2 路绑定已经表明他想要绑定属性。没有?
    • @Tengiz:不是真的。您可以将Name(普通)属性绑定到TextBlockText(依赖)属性,并使用2 路模式。 &lt;TextBlock Text="{Binding Name, Mode=TwoWay}"
    • 你认为这有道理吗?对此文本块的任何更改都不会影响 name 属性,因此此 TwoWay 的行为与 OneWay 完全一样。没有?
    • 是的,它确实会影响它。尽管我很确定,但我还是再次尝试了,效果很好!
    • 那么你有一个类,它有一个受控件绑定影响的非依赖只读属性?我不相信这一点:-)但我明白了,你的意思是类属性不是只读的。你想在文本块上看到的属性的变化呢?
    猜你喜欢
    • 2019-02-12
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    • 1970-01-01
    • 2010-10-17
    相关资源
    最近更新 更多