基于 DataContext 设置的 WPF 按钮内容

Dan*_*rez 4 c# wpf

我正在使用 WPF 和 MVVM 模式,我有一个由按钮组成的简单视图,它应该根据 DataContext(视图模型)的属性显示一件事或另一件事我已经使用数据触发器和数据模板来尝试使这项工作,但由于某种原因绑定没有评估(或者我做错了什么)。

    <Button x:Class="EpicNavalBattle.View.PositionView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 

        >
    <Button.Resources>
        <DataTemplate x:Key="Hidden">
            <Label Content="Hidden"></Label>
        </DataTemplate>
        <DataTemplate x:Key="Shown">
            <Label Content="{Binding Path=Content.ContentName}" />
        </DataTemplate>



    </Button.Resources>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Revealed}" Value="False">
                    <Setter Property="ContentTemplate" Value="{DynamicResource Hidden}"></Setter>

                </DataTrigger>
                <DataTrigger Binding="{Binding Revealed}" Value="True">
                    <Setter Property="ContentTemplate" Value="{DynamicResource Shown}"></Setter>

                </DataTrigger>
            </Style.Triggers>
        </Style>

    </Button.Style>


</Button>
Run Code Online (Sandbox Code Playgroud)

只是为了避免混淆:Content 是 ViewModel(继承的数据上下文)的属性,它基本上是 Model 类,ContentName 是 Model 类的属性。对整个数据模板进行了评估,因为为了证明这一点,我更改了文本的 Content="Binding...." 内容,它实际上显示了一个带有指定标签的按钮。现在,我看到的只是没有文字的按钮(小,最小尺寸)任何帮助表示赞赏(不仅关于如何解决这个问题,而且关于我在这里做错了什么)。谢谢!

Arc*_*rus 5

我测试了您的代码示例,问题是:

ContentControls例如 Button,将它们的内容设置DataContextDataTemplate. 因此,当您绑定到 时DataContext,您实际上绑定到了按钮的内容。

您可以通过两种方式解决它:

{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=DataContext.Content.ContentName}
Run Code Online (Sandbox Code Playgroud)

或者将值设置为触发器中的内容:

<Setter Property="Content" Value="{Binding Content.ContentName}"></Setter>
Run Code Online (Sandbox Code Playgroud)

使用 Hidden 顺便说一句,最后一个解决方案也会更容易,因此您可以丢弃这些模板:

            <Button.Style>
                <Style TargetType="{x:Type Button}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Revealed}" Value="True">
                                <Setter Property="Content" Value="{Binding Content.ContentName}"></Setter>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Revealed}" Value="False">
                                <Setter Property="Content" Value="Hidden"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
Run Code Online (Sandbox Code Playgroud)

额外奖励:超短解决方案:

<Style TargetType="{x:Type Button}">
    <Setter Property="Content" Value="Hidden" />
    <Style.Triggers>
        <DataTrigger Binding="{Binding Revealed}" Value="True">
            <Setter Property="Content" Value="{Binding Content.ContentName}" />
        </DataTrigger>
    </Style.Triggers>
</Style>
Run Code Online (Sandbox Code Playgroud)