【问题标题】:How to make a custom WPF collection?如何制作自定义 WPF 集合?
【发布时间】:2009-07-16 01:25:52
【问题描述】:

我正在尝试创建一组可以通过 XAML 添加到 WPF 控件的自定义类。

我遇到的问题是将项目添加到集合中。这是我目前所拥有的。

public class MyControl : Control
{
    static MyControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));
    }

    public static DependencyProperty MyCollectionProperty = DependencyProperty.Register("MyCollection", typeof(MyCollection), typeof(MyControl));
    public MyCollection MyCollection
    {
        get { return (MyCollection)GetValue(MyCollectionProperty); }
        set { SetValue(MyCollectionProperty, value); }
    }
}

public class MyCollectionBase : DependencyObject
{
    // This class is needed for some other things...
}

[ContentProperty("Items")]
public class MyCollection : MyCollectionBase
{
    public ItemCollection Items { get; set; }
}

public class MyItem : DependencyObject { ... }

还有 XAML。

<l:MyControl>
    <l:MyControl.MyCollection>
        <l:MyCollection>
            <l:MyItem />
        </l:MyCollection>
    </l:MyControl.MyCollection>
</l:MyControl>

例外是:
System.Windows.Markup.XamlParseException occurred Message="'MyItem' object cannot be added to 'MyCollection'. Object of type 'CollectionTest.MyItem' cannot be converted to type 'System.Windows.Controls.ItemCollection'.

有人知道我该如何解决这个问题吗?谢谢

【问题讨论】:

  • 您能否从 System.Collections.ObjectModel 中以 DOM 为中心的集合类之一继承您的基类?这些类(例如 Collection、KeyedCollection 等)非常适合创建 DOM 样式接口,因为它们支持可覆盖的添加/删除功能。我知道这不是对您问题的直接回答,但想知道是否有理由不这样做?

标签: .net wpf xaml collections


【解决方案1】:

经过更多谷歌搜索,我发现 this 博客有相同的错误消息。看来我也需要实现 IList。

public class MyCollection : MyCollectionBase,  IList
{
    // IList implementation...
}

【讨论】:

  • 这与您的原始代码不同 - 它会将项目添加到 MyCollection 本身,而不是其 Items 属性。
【解决方案2】:

您是否忘记在MyCollection 的构造函数中创建ItemCollection 的实例,并将其分配给Items 属性? XAML 解析器要添加项目,它需要一个现有的集合实例。它不会为您创建一个新的(尽管如果集合属性有一个 setter,它将允许您在 XAML 中显式创建一个)。所以:

[ContentProperty("Items")]
public class MyCollection : MyCollectionBase
{
    public ObservableCollection<object> Items { get; private set; }

    public MyCollection()
    {
         Items = new ObservableCollection<object>();
    }
}

【讨论】:

  • ItemCollection 没有公共属性。有没有其他方法可以创建它?
  • 对不起,我的意思是没有公共构造函数。
  • 好点 - 看起来像是 internal,实际上仅供 ItemsControl 使用。因此,要么派生自 ItemsControl(如果它对您的类有意义),要么使用任何其他 XAML 支持的集合类,例如 ObservableCollection&lt;T&gt;。我已经相应地更新了示例。
猜你喜欢
  • 2011-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多