UserControl với ContextMenu wpf

Aug 21 2020

Tôi đang cố gắng tạo UserControl nút bằng ContextMenu để có khả năng chuyển văn bản và hình ảnh cụ thể sang ngữ cảnh nút. Nhưng tôi không biết cách liên kết các mục ContextMenu đúng cách và chỉ định chúng thông qua xaml hoặc ràng buộc.

Tôi đã cố gắng chỉ định điều khiển như thế này với ContentPresenter bên trong khối 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>

Và cách tôi đã sử dụng trong chế độ xem

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

Nhưng các món trong thực đơn của tôi hiển thị dưới dạng một phần tử duy nhất

Ngoài ra, tôi đã cố gắng chỉ định IEnumerable DependencyProperty và ràng buộc ContextMenu trên các mục nhưng điều này không hiệu quả với tôi. Tôi có thể làm gì?

Trả lời

1 mm8 Aug 21 2020 at 21:07

Thêm thuộc tính chỉ đọc Danh sách vào UserControltác phẩm:

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); }
    }

    ...
}

Ràng buộc với tài sản trong 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>

Và đặt nó như thế này:

<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>