我有一个自定义菜单,其中的 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
属性。
这可能吗?有更好的办法吗?
我尝试制作一个继承自
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));
}
这允许我绑定到我的属性,但现在菜单不出现。有什么想法吗?
我设法找到了解决方法。在
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>
这不是我一直在寻找的优雅装订解决方案,但它确实有效。