C# 重复上下文菜单菜单项';UserControl中的ObservableCollection DependencyProperty中的s

C# 重复上下文菜单菜单项';UserControl中的ObservableCollection DependencyProperty中的s,c#,wpf,xaml,C#,Wpf,Xaml,由于某些原因,当我重用usercontrol时,即使我只指定了1个menuitem,也会有重复的上下文菜单项 例如,测试1和测试2菜单项出现在两个用户控件中,即使它们在单独的用户控件中编码 我的主窗口看起来像 <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDef

由于某些原因,当我重用usercontrol时,即使我只指定了1个menuitem,也会有重复的上下文菜单项

例如,测试1和测试2菜单项出现在两个用户控件中,即使它们在单独的用户控件中编码

我的主窗口看起来像

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <local:OptionsMenu Grid.Row="0" MenuWidth="23" MenuHeight="7">
            <local:OptionsMenu.MenuItems>
                <MenuItem Header="Test 1"/>
            </local:OptionsMenu.MenuItems>
        </local:OptionsMenu>

        <local:OptionsMenu Grid.Row="1" MenuWidth="23" MenuHeight="7">
            <local:OptionsMenu.MenuItems>
                <MenuItem Header="Test 2"/>
            </local:OptionsMenu.MenuItems>
        </local:OptionsMenu>
    </Grid>
</Window>
<UserControl.Resources>
        <Style TargetType="{x:Type Button}" x:Key="MenuButton">

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Canvas>
                            <Path Data="M12.5,6.5 C12.5,9.8137085 9.8137085,12.5 6.5,12.5 C3.1862915,12.5 0.5,9.8137085 0.5,6.5 C0.5,3.1862915 3.1862915,0.5 6.5,0.5 C9.8137085,0.5 12.5,3.1862915 12.5,6.5 z M30.5,6.5 C30.5,9.8137085 27.813708,12.5 24.5,12.5 C21.186292,12.5 18.5,9.8137085 18.5,6.5 C18.5,3.1862915 21.186292,0.5 24.5,0.5 C27.813708,0.5 30.5,3.1862915 30.5,6.5 z M48.5,6.5 C48.5,9.8137085 45.813708,12.5 42.5,12.5 C39.186292,12.5 36.5,9.8137085 36.5,6.5 C36.5,3.1862915 39.186292,0.5 42.5,0.5 C45.813708,0.5 48.5,3.1862915 48.5,6.5 z" 
                                    Fill="Black" 
                                    HorizontalAlignment="Left" 
                                    Stretch="Fill" 
                                    Stroke="Black"
                                    VerticalAlignment="Top" 
                                    Height="{Binding MenuHeight}" 
                                    Width="{Binding MenuWidth}" />
                            <ItemsPresenter />
                        </Canvas>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>


    <Grid>
        <Button x:Name="Root" Style="{DynamicResource MenuButton}" Click="Button_Click">
            <Button.ContextMenu >
                <ContextMenu ItemsSource="{Binding MenuItems}" />
            </Button.ContextMenu>
        </Button>
    </Grid>
</UserControl>

我的用户控件看起来像

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <local:OptionsMenu Grid.Row="0" MenuWidth="23" MenuHeight="7">
            <local:OptionsMenu.MenuItems>
                <MenuItem Header="Test 1"/>
            </local:OptionsMenu.MenuItems>
        </local:OptionsMenu>

        <local:OptionsMenu Grid.Row="1" MenuWidth="23" MenuHeight="7">
            <local:OptionsMenu.MenuItems>
                <MenuItem Header="Test 2"/>
            </local:OptionsMenu.MenuItems>
        </local:OptionsMenu>
    </Grid>
</Window>
<UserControl.Resources>
        <Style TargetType="{x:Type Button}" x:Key="MenuButton">

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Button}">
                        <Canvas>
                            <Path Data="M12.5,6.5 C12.5,9.8137085 9.8137085,12.5 6.5,12.5 C3.1862915,12.5 0.5,9.8137085 0.5,6.5 C0.5,3.1862915 3.1862915,0.5 6.5,0.5 C9.8137085,0.5 12.5,3.1862915 12.5,6.5 z M30.5,6.5 C30.5,9.8137085 27.813708,12.5 24.5,12.5 C21.186292,12.5 18.5,9.8137085 18.5,6.5 C18.5,3.1862915 21.186292,0.5 24.5,0.5 C27.813708,0.5 30.5,3.1862915 30.5,6.5 z M48.5,6.5 C48.5,9.8137085 45.813708,12.5 42.5,12.5 C39.186292,12.5 36.5,9.8137085 36.5,6.5 C36.5,3.1862915 39.186292,0.5 42.5,0.5 C45.813708,0.5 48.5,3.1862915 48.5,6.5 z" 
                                    Fill="Black" 
                                    HorizontalAlignment="Left" 
                                    Stretch="Fill" 
                                    Stroke="Black"
                                    VerticalAlignment="Top" 
                                    Height="{Binding MenuHeight}" 
                                    Width="{Binding MenuWidth}" />
                            <ItemsPresenter />
                        </Canvas>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>


    <Grid>
        <Button x:Name="Root" Style="{DynamicResource MenuButton}" Click="Button_Click">
            <Button.ContextMenu >
                <ContextMenu ItemsSource="{Binding MenuItems}" />
            </Button.ContextMenu>
        </Button>
    </Grid>
</UserControl>

背后的代码

public ObservableCollection<DependencyObject> MenuItems
        {
            get { return (ObservableCollection<DependencyObject>)GetValue(MenuItemsProperty); }
            set { SetValue(MenuItemsProperty, value); }
        }

        internal static readonly DependencyProperty MenuItemsProperty = DependencyProperty.Register(
            "MenuItems", typeof(ObservableCollection<DependencyObject>), typeof(OptionsMenu),
            new FrameworkPropertyMetadata(new ObservableCollection<DependencyObject>()));
公共可观测集合菜单项
{
get{return(ObservableCollection)GetValue(MenuItemsProperty);}
集合{SetValue(MenuItemsProperty,value);}
}
内部静态只读DependencyProperty MenuItemsProperty=DependencyProperty.Register(
“菜单项”、类型(可观察采集)、类型(选项菜单),
新的FrameworkPropertyMetadata(新的ObservableCollection());

原因是您正在为可变引用类型的依赖项属性使用非空默认值

控件的所有实例都使用相同的默认值,即相同的
observetecollection
实例,由

new FrameworkPropertyMetadata(new ObservableCollection<DependencyObject>())
并通过
SetCurrentValue
在控件的构造函数中分配初始值,这与
SetValue
不同,仍然允许按样式和触发器设置器和类似源设置其他值:

public OptionsMenu()
{
    SetCurrentValue(MenuItemsProperty,
        new ObservableCollection<DependencyObject>());
}
公共选项菜单()
{
SetCurrentValue(菜单项属性,
新的可观测集合();
}

原因是您正在为可变引用类型的依赖项属性使用非空默认值

控件的所有实例都使用相同的默认值,即相同的
observetecollection
实例,由

new FrameworkPropertyMetadata(new ObservableCollection<DependencyObject>())
并通过
SetCurrentValue
在控件的构造函数中分配初始值,这与
SetValue
不同,仍然允许按样式和触发器设置器和类似源设置其他值:

public OptionsMenu()
{
    SetCurrentValue(MenuItemsProperty,
        new ObservableCollection<DependencyObject>());
}
公共选项菜单()
{
SetCurrentValue(菜单项属性,
新的可观测集合();
}

您可以向我们展示整个XAMLs吗?我已经更新了我的XAMLs。根据答案中的解释,不清楚您为什么认为需要使用ObservableCollection作为属性类型。一个普通的
列表
也可以。你能给我们展示整个XAMLs吗?我已经更新了我的XAMLs。根据答案中的解释,不清楚你为什么认为需要使用ObservableCollection作为属性类型。普通的
列表
也可以工作。