WPF - 使用动态子控件创建自定义控件

时间:2015-12-29 15:27:00

标签: wpf xaml mvvm custom-controls

我正在尝试在WPF中创建一个菜单/导航控件,用于跨多个应用程序。该控件旨在驻留在自定义窗口中,并将提供最大化,最小化,关闭,拖动等功能。除了标准的“窗口”功能外,控件还应该包含应用程序的主“菜单” - 本质上是每个与命令和/或视图模型相关联的按钮集合 - 这些按钮也是自定义控件(派生的)来自单选按钮)。

基本上,我的目标是能够通过XAML以这样的方式添加此菜单控件及其按钮(这是伪代码,要清楚):

    <MenuControl Title="ApplicationTitle>
        <MenuControl.MenuButtons>
            <MenuButton Content="Button1" Command="Command1"/>
            <MenuButton Content="Button2" Command="Command2"/>
        </MenuControl.MenuButtons>
    </MenuControl>

我已经达到了这样的程度,我只能在一个按钮上正常工作。一旦我添加了第二个按钮,我的XAML就会出现“指定参数超出有效值的范围”。

以下是与我的自定义控件上的菜单相关的代码隐藏:

    private static readonly DependencyProperty MenuProperty = DependencyProperty.Register("Menu", typeof(ObservableCollection<NavigationButton>), typeof(CCTNavigationHeader), new FrameworkPropertyMetadata(new ObservableCollection<NavigationButton>()));

    public ObservableCollection<NavigationButton> Menu
    {
        get
        {
            return (ObservableCollection<NavigationButton>)GetValue(MenuProperty);
        }
        set
        {
            SetValue(MenuProperty, value);
        }
    }

这是XAML:

    <ItemsControl ItemsSource="{Binding ElementName=ctlCCTNavigationHeader, Path=Menu}"/>

这是使用控件的代码,只有一个按钮:

    <Controls:CCTNavigationHeader Title="Test">
        <Controls:CCTNavigationHeader.Menu>
            <Controls:NavigationButton Content="Test"/>
        </Controls:CCTNavigationHeader.Menu>
    </Controls:CCTNavigationHeader>

这是使用控件扼杀的代码,一旦我添加了第二个按钮:

    <Controls:CCTNavigationHeader Title="Test">
        <Controls:CCTNavigationHeader.Menu>
            <Controls:NavigationButton Content="Test"/>
            <Controls:NavigationButton Content="Test"/>
        </Controls:CCTNavigationHeader.Menu>
    </Controls:CCTNavigationHeader>

我知道我必须在这里做错事,但我无法在任何地方找到任何完成此类解决方案的例子。任何熟悉在WPF中创建自定义用户控件的人都能指出我正确的方向吗?

1 个答案:

答案 0 :(得分:0)

想出这个。我在创建控件时没有初始化Menu集合。以下代码修复了它:

    public CCTNavigationHeader()
    {
        InitializeComponent();
        Menu = new ObservableCollection<NavigationButton>(); //this line
    }