UserControl avec ContextMenu wpf

Aug 21 2020

J'essaie de créer un bouton UserControl avec ContextMenu pour pouvoir transmettre un texte et une image spécifiques au contexte du bouton. Mais je ne sais pas comment lier correctement les éléments ContextMenu et les spécifier via xaml ou la liaison.

J'ai essayé de spécifier un contrôle comme celui-ci avec ContentPresenter dans le bloc ContextMenu.

<UserControl.Template>
   <ControlTemplate TargetType="UserControl">
      <Button Style="{StaticResource HeaderButton}" app:ContextMenuLeftClickBehavior.IsLeftClickEnabled="True">
         <Button.Content>
            <StackPanel Orientation="Horizontal">
               <Image Source="{Binding ImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MenuControl}}}" />
               <TextBlock Text="{Binding Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MenuControl}}}" />
               <Path Stroke="Black"
                  StrokeThickness="1"
                  Margin="5 0 5 0"
                  Data="M 0 4 L 5 10 M 5 10 L 10 4" />
            </StackPanel>
         </Button.Content>
         <Button.ContextMenu>
            <ContextMenu>
               <ContentPresenter />
            </ContextMenu>
         </Button.ContextMenu>
      </Button>
   </ControlTemplate>
</UserControl.Template>

Et comment j'ai utilisé en vue

<control:MenuControl ImageSource="Icons/TestPlan.png" Text="Load">
   <StackPanel>
      <MenuItem Header="test1" />
      <MenuItem Header="test2" />
   </StackPanel>
</control:MenuControl>

Mais mes éléments de menu s'affichaient comme un seul élément.

De plus, j'ai essayé de spécifier IEnumerable DependencyProperty et de lier ContextMenu sur les éléments, mais cela n'a pas fonctionné pour moi. Que puis-je faire s'il vous plaît ?

Réponses

1 mm8 Aug 21 2020 at 21:07

Ajout d'une propriété List en lecture seule aux UserControltravaux :

public partial class MenuControl : UserControl
{
    public MenuControl()
    {
        InitializeComponent();
        SetValue(ItemsPropertyKey, new List<MenuItem>());
    }

    private static readonly DependencyPropertyKey ItemsPropertyKey = DependencyProperty.RegisterReadOnly(
      nameof(Items),
      typeof(List<MenuItem>),
      typeof(MenuControl),
      new FrameworkPropertyMetadata(null)
    );

    public static readonly DependencyProperty ItemsProperty = ItemsPropertyKey.DependencyProperty;

    public List<MenuItem> Items
    {
        get { return (List<MenuItem>)GetValue(ItemsProperty); }
    }

    ...
}

Lier à la propriété dans le ControlTemplate:

<ControlTemplate TargetType="UserControl">
    <Button>
        <Button.Content>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding ImageSource, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MenuControl}}}" />
                <TextBlock Text="{Binding Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MenuControl}}}" />
                <Path Stroke="Black"
                      StrokeThickness="1"
                      Margin="5 0 5 0"
                      Data="M 0 4 L 5 10 M 5 10 L 10 4" />
            </StackPanel>
        </Button.Content>
        <Button.Tag>
            <Binding RelativeSource="{RelativeSource AncestorType={x:Type local:MenuControl}}" />
        </Button.Tag>
        <Button.ContextMenu>
            <ContextMenu ItemsSource="{Binding PlacementTarget.Tag.Items, RelativeSource={RelativeSource Self}}" />
        </Button.ContextMenu>
    </Button>
</ControlTemplate>

Et réglez-le comme ceci :

<control:MenuControl x:Name="cc" ImageSource="Icons/TestPlan.png" Text="Load">
    <control:MenuControl.Items>
        <MenuItem Header="test1" />
        <MenuItem Header="test2" />
    </control:MenuControl.Items>
</control:MenuControl>