【问题标题】:How to update a custom dependency property when the datasource list changes数据源列表更改时如何更新自定义依赖项属性
【发布时间】:2011-02-07 00:28:40
【问题描述】:

我们有一个带有自定义依赖属性 (DP) 的用户控件。 DP 绑定到 ObservableCollection。

当以编程方式将新项目添加到集合中时,数据绑定不会更新目标 DP。为什么?我们认为这是因为,不幸的是,在我们的例子中,目标不是 ListBox 或 ListView,而是 Canvas。 DP 在更改或初始化时应该在 Canvas 上绘制一个 Shape (!),并且 shape 的位置和大小绑定到集合项的两个属性:WIDTH、LEFT。

理想情况下,我们不想仅仅因为添加(或删除)一项就清除画布并重新绘制所有项目。但是怎么做呢?

所以: 自定义 DP 如何负责为新收藏项绘制形状?我们需要什么回调,这必须在什么时间点发生,可能会有哪些特定的 MetaDataOptions?

另外,关于所有这些依赖属性选项,是否有任何好的资源。他们很混乱。 MSDN 对我们正在尝试做的事情并没有真正的帮助。

谢谢!

编辑:

ObservableCollection 是这样的:

public class Projects : ObservableCollection<Project>
{
    //no ommitted code. this class really IS empty!
}

DP是这样的:

public class MyUserControl : UserContorl
{
  public static readonly DependencyProperty... etc. typeof(Projects)

  private static void OnProjectsChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        MyUserControl u = d as MyUserControl;
        CpProjectCollection projects = e.NewValue as CpProjectCollection;
        u.Refresh(projects);
    }

private void Refresh(CpProjectCollection projects)
        {
           foreach (CpProject p in projects)
            {
              //...add each project to the Canvas
              ProjectContorl pc = new ProjectControl();
              pc.Project = project;

              Binding b = new Binding("StartTime");
              b.Converter = new TimeSpanConverter();
              b.Source = pc.Project;
              b.Mode = BindingMode.TwoWay;
              c.SetBinding(Canvas.LeftProperty, b); 

              //do the same for project duration
            }
        }
    }

【问题讨论】:

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


    【解决方案1】:
    1. 如果您绑定到ObservableCollection,如果集合被另一个集合替换,您会收到更改通知,而不是当集合的内容发生更改时。因此,您需要在代码隐藏中订阅 CollectionChanged 事件。
    2. 如果您订阅了CollectionChanged,您可以在ObservableCollection 中查看哪些new/deleted items。您可以为每个new item 添加一个新形状,并为deleted items 删除旧形状。

    【讨论】:

    • 好的!这是第一步......但是如果 DP 绑定到集合,我何时何地将受影响的项目添加到画布?这会发生在回调中,还是我需要某些 MetaDataOptions,或两者兼而有之?我不知道这是如何工作的。另外,如果画布上有 10 个形状,并且删除了一个集合项,我如何知道 10 个形状中的哪一个代表删除的项?
    • 再想一想,不,ObservableCollection 已经实现了 INotifyCollectionChanged,因此它会在添加或删除项目时触发 CollectionChanged 事件!这应该是默认行为。我们在这里做错了什么?
    • @John:您订阅了CollectionChanged 事件吗?也许你可以发布你的代码并告诉你到底哪里错了?如果您只是将某些内容绑定到ObservableCollection,则绑定不会在CollectionChanged 上侦听。 :-(
    • 我在上面发布了我的代码。如您所见,我不订阅任何活动。我将在 MyUserControl 中的何处以及如何执行此操作?谢谢!
    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 2013-10-25
    • 2017-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多