控件模板中的 WPF XAML 菜单绑定

问题描述 投票:0回答:1

我有一个自定义菜单,其中的 ItemsSource 绑定到视图模型中的 ObservableCollection。为了自定义菜单,我在样式中使用 ControlTemplate,并且 ControlTemplate 包含一个标签。我想根据我的

IsDefault
类中的
MenuItem
属性显示或隐藏此标签。

这是简化的 xaml:

<Menu x:Name="RewriteMenu" ItemsSource="{Binding RewriteMenuItems}"Margin="0,10,10,0" >
    <Menu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="Header" Value="{Binding Name}" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <Border x:Name="Border" Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"
                                    CornerRadius="6">
                            <Grid Margin="0,0,0,0" Background="{TemplateBinding Background}"
                                      VerticalAlignment="Center">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto"
                                                          SharedSizeGroup="MenuItemIconColumnGroup" />
                                    <ColumnDefinition Width="Auto"
                                                          SharedSizeGroup="MenuTextColumnGroup" />
                                    <ColumnDefinition Width="Auto"
                                                          SharedSizeGroup="MenuItemIGTColumnGroup" />
                                    <ColumnDefinition x:Name="Col3" Width="150" />
                                    <ColumnDefinition x:Name="Col4" Width="Auto" />
                                </Grid.ColumnDefinitions>

                                <!--ContentPresenter to show an Icon if needed-->

                                <ContentPresenter Grid.Column="0" Margin="14,0,6,0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon" Width="18" Height="18" />

                                <!--Content for the menu text etc-->
                                <TextBlock Height="27" FontFamily="{StaticResource PoppinsRegular}" VerticalAlignment="Center" Width="260" Grid.Column="1" x:Name="HeaderHost"
               Text="{TemplateBinding Header}" />

<Label Grid.Column="2" Style="{StaticResource DefaultVoiceStyle}" Background="#BFCBFF" Visibility="{Binding Content.IsDefault, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolToVisConverter}}"/>
                                <
        </Style>
    </Menu.ItemContainerStyle>
    <Menu.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" Width="340" />
        </ItemsPanelTemplate>
    </Menu.ItemsPanel>
</Menu>

我找到了这个答案,所以我尝试了类似的方法:

<Label Visibility="{Binding Content.IsDefault, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolToVisConverter}}"/>
,但是这个绑定只能让我到达MenuItem(WPF版本,而不是我的自定义类。抱歉,我的命名不好),我不能绑定到
IsDefault
属性。

这可能吗?有更好的办法吗?

UDP日期

我尝试制作一个继承自

System.Windows.Controls.MenuItem
的自定义MenuItem:

public class VoiceRewriteMenuItem : MenuItem
{
    public bool IsDefault
    {
        get { return (bool)GetValue(IsDefaultProperty); }
        set { SetValue(IsDefaultProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsDefault.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsDefaultProperty =
        DependencyProperty.Register("IsDefault", typeof(bool), typeof(VoiceRewriteMenuItem), new PropertyMetadata(false));
}

这允许我绑定到我的属性,但现在菜单不出现。有什么想法吗?

wpf xaml data-binding wpf-controls
1个回答
0
投票

我设法找到了解决方法。在

System.Windows.Control.MenuItem
中,有一些我不关心的布尔属性。我将
IsChecked
属性绑定到视图模型中的
IsDefault
属性,并将标签可见性设置为仅当
MenuItem.IsChecked
为 true 时才可见。所以它的工作原理是这样的:

<Menu x:Name="RewriteMenu" ItemsSource="{Binding RewriteMenuItems}"Margin="0,10,10,0" >
    <Menu.ItemContainerStyle>
        <Style TargetType="{x:Type MenuItem}">
            <Setter Property="Header" Value="{Binding Name}" />
            <Setter Property="IsChecked" Value="{Binding IsDefault}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type MenuItem}">
                        <Border x:Name="Border" Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1"
                                    CornerRadius="6">
                            <Grid Margin="0,0,0,0" Background="{TemplateBinding Background}"
                                      VerticalAlignment="Center">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition x:Name="Col0" MinWidth="17" Width="Auto"
                                                          SharedSizeGroup="MenuItemIconColumnGroup" />
                                    <ColumnDefinition Width="Auto"
                                                          SharedSizeGroup="MenuTextColumnGroup" />
                                    <ColumnDefinition Width="Auto"
                                                          SharedSizeGroup="MenuItemIGTColumnGroup" />
                                    <ColumnDefinition x:Name="Col3" Width="150" />
                                    <ColumnDefinition x:Name="Col4" Width="Auto" />
                                </Grid.ColumnDefinitions>

                                <!--ContentPresenter to show an Icon if needed-->

                                <ContentPresenter Grid.Column="0" Margin="14,0,6,0" x:Name="Icon" VerticalAlignment="Center" ContentSource="Icon" Width="18" Height="18" />

                                <!--Content for the menu text etc-->
                                <TextBlock Height="27" FontFamily="{StaticResource 
                                           PoppinsRegular}" 
                                           VerticalAlignment="Center" Width="260" 
                                           Grid.Column="1" x:Name="HeaderHost"
                                           Text="{TemplateBinding Header}" />

                                 <Label Grid.Column="2" Style="{StaticResource DefaultVoiceStyle}" Background="#BFCBFF" Visibility="{Binding Content.IsChecked, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisConverter}}"/>
                                
        </Style>
    </Menu.ItemContainerStyle>
    <Menu.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" Width="340" />
        </ItemsPanelTemplate>
    </Menu.ItemsPanel>
</Menu>

这不是我一直在寻找的优雅装订解决方案,但它确实有效。

© www.soinside.com 2019 - 2024. All rights reserved.