ContextMenu - 使用 ItemContainerStyle 时的奇怪行为
ContextMenu - Strange behavior when using ItemContainerStyle
我的 ContextMenu
遇到了一个奇怪的问题。 ItemsSource
是一个 List<Layer> Layers;
,其中 Layer
class 覆盖 ToString()
到 return Name
属性 .
如果我不为上下文菜单使用任何 ItemContainerStyle
,它一切正常 - 它接受 Layer
对象并显示该对象的 ToString()
,喜欢它应该。当我添加 ItemContainerStyle
时,它显示一个空字符串。
这是 XAML:
<Style x:Key="myItemControlTemplate" TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border SnapsToDevicePixels="True" Height="32" Width="200" Background="White">
<Grid VerticalAlignment="Center" Height="Auto" Width="Auto" Background="{x:Null}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{TemplateBinding Header}" VerticalAlignment="Top" Foreground="#FF3B3D52"
Grid.Column="1" Margin="6,0,0,0"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button ContextMenuService.IsEnabled="False">
<Button.ContextMenu>
<ContextMenu FontFamily="Global Sans Serif" Height="Auto" Width="200" Padding="0,6" VerticalOffset="5" BorderThickness="0"
HasDropShadow="True" ItemContainerStyle="{StaticResource myItemControlTemplate}">
</ContextMenu>
</Button.ContextMenu>
</Button>
我是这样触发它的:
private void btn_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
ContextMenu ctm = btn.ContextMenu;
ctm.ItemsSource = Layers;
ctm.PlacementTarget = btn;
ctm.Placement = PlacementMode.Bottom;
ctm.IsOpen = true;
}
会不会是因为某种原因这个绑定被破坏了?
Text="{TemplateBinding Header}"
顺便说一句,如果我将层列表更改为 List<string>
并仅向其提供层的名称,它可以与 ItemContainerStyle
.
一起正常工作
我错过了什么?
问题是TemplateBinding
。这是相对源绑定到模板化父级的一个功能较弱但经过优化的变体,但它以几个限制为代价,比如不支持双向绑定。尽管文档中没有正式说明,但似乎此绑定不支持将基础类型转换为 string
,因为在这种情况下从未调用 ToString
。
将 TemplateBinding
替换为使用相对源的模板化父项的绑定。
<TextBlock x:Name="textBlock"
HorizontalAlignment="Left" TextWrapping="Wrap"
Text="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="Top" Foreground="#FF3B3D52"
Grid.Column="1" Margin="6,0,0,0"/>
我的 ContextMenu
遇到了一个奇怪的问题。 ItemsSource
是一个 List<Layer> Layers;
,其中 Layer
class 覆盖 ToString()
到 return Name
属性 .
如果我不为上下文菜单使用任何 ItemContainerStyle
,它一切正常 - 它接受 Layer
对象并显示该对象的 ToString()
,喜欢它应该。当我添加 ItemContainerStyle
时,它显示一个空字符串。
这是 XAML:
<Style x:Key="myItemControlTemplate" TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<Border SnapsToDevicePixels="True" Height="32" Width="200" Background="White">
<Grid VerticalAlignment="Center" Height="Auto" Width="Auto" Background="{x:Null}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="textBlock" HorizontalAlignment="Left" TextWrapping="Wrap" Text="{TemplateBinding Header}" VerticalAlignment="Top" Foreground="#FF3B3D52"
Grid.Column="1" Margin="6,0,0,0"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button ContextMenuService.IsEnabled="False">
<Button.ContextMenu>
<ContextMenu FontFamily="Global Sans Serif" Height="Auto" Width="200" Padding="0,6" VerticalOffset="5" BorderThickness="0"
HasDropShadow="True" ItemContainerStyle="{StaticResource myItemControlTemplate}">
</ContextMenu>
</Button.ContextMenu>
</Button>
我是这样触发它的:
private void btn_Click(object sender, RoutedEventArgs e)
{
Button btn = sender as Button;
ContextMenu ctm = btn.ContextMenu;
ctm.ItemsSource = Layers;
ctm.PlacementTarget = btn;
ctm.Placement = PlacementMode.Bottom;
ctm.IsOpen = true;
}
会不会是因为某种原因这个绑定被破坏了?
Text="{TemplateBinding Header}"
顺便说一句,如果我将层列表更改为 List<string>
并仅向其提供层的名称,它可以与 ItemContainerStyle
.
我错过了什么?
问题是TemplateBinding
。这是相对源绑定到模板化父级的一个功能较弱但经过优化的变体,但它以几个限制为代价,比如不支持双向绑定。尽管文档中没有正式说明,但似乎此绑定不支持将基础类型转换为 string
,因为在这种情况下从未调用 ToString
。
将 TemplateBinding
替换为使用相对源的模板化父项的绑定。
<TextBlock x:Name="textBlock"
HorizontalAlignment="Left" TextWrapping="Wrap"
Text="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"
VerticalAlignment="Top" Foreground="#FF3B3D52"
Grid.Column="1" Margin="6,0,0,0"/>