创建动态可扩展工具箱

时间:2015-02-24 13:46:27

标签: c# wpf menu itemscontrol multiple-instances

我正在尝试创建一个动态可扩展工具箱,如下图所示。 enter image description here

自定义控件会根据可用空间将不同的项目放在基本和高级菜单中。如果有足够的空间显示基本菜单中的所有项目,则不会显示高级菜单。 我创建了这个控件,只要我在应用程序中只使用一次它就可以工作。如果我多次实例化,我会得到下面的例外,我很难理解,因为我只是在非静态列表中添加一个元素。

Exception 是否有人对如何以不同方式创建此控件以避免此问题或知道是什么创建此异常有另一个想法?

链接到解决方案:ButtonsItemsControl(要重现问题,请取消注释MainWindow.xaml的第15行

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:0)

您的问题在于ButtonsItemsControl类的依赖属性声明:

public ObservableCollection<FrameworkElement> BasedMenuItems
{
    get { return (ObservableCollection<FrameworkElement>)GetValue(BasedMenuItemsProperty); }
    set { SetValue(BasedMenuItemsProperty, value); }
}
public static readonly DependencyProperty BasedMenuItemsProperty =
        DependencyProperty.Register("BasedMenuItems", typeof(ObservableCollection<FrameworkElement>), typeof(ButtonsItemsControl),
        new PropertyMetadata(new ObservableCollection<FrameworkElement>()));

您为该依赖项属性设置了一个默认值,该属性是ObservableCollection<FrameworkElement>的一个实例。问题是,执行此行时会创建此实例,即在内存中加载类并初始化静态字段时。这意味着,如果不覆盖这些属性, ButtonsItemsControl的每个实例将共享相同的集合对象。

您应该删除PropertyMetadata构造函数中的默认值,而是在实例化控件时在其自己的构造函数中设置一个新值:

public ButtonsItemsControl()
{
    BasedMenuItems = new ObservableCollection<FrameworkElement>();
    ...
}

这似乎是违反直觉的,但据我所知,没有更好的方法(实际上框架在内部使用工厂对象创建新的类实例以产生唯一的默认值,但无论出于何种原因,他们都没有将这些工厂暴露在外面框架)。