【问题标题】:ContextMenu - Strange behavior when using ItemContainerStyleContextMenu - 使用 ItemContainerStyle 时的奇怪行为
【发布时间】:2021-03-26 21:56:53
【问题描述】:

我的ContextMenu 有一个奇怪的问题。 ItemsSource 是一个List<Layer> Layers;,其中Layer 类覆盖ToString() 以返回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&lt;string&gt; 并只提供层的名称,它可以与 ItemContainerStyle 一起正常工作。

我错过了什么?

【问题讨论】:

    标签: wpf xaml contextmenu itemcontainerstyle


    【解决方案1】:

    问题是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"/>
    

    【讨论】:

    • 每天学点东西!感谢您的解释。干杯。
    猜你喜欢
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多