wpf - 通过 setter v ContentTemplate 设置内容样式

标签 wpf xaml data-binding mvvm styles

第一种样式的 xaml 可以按我的意愿工作,使用 setter 生成一个带有 Wingding 字形的按钮来布置内容及其属性。这种风格的第二个版本试图做同样的事情,但使用 DataTemplate 作为 Content,但它只显示 DataTemplate 的类型(即 System.Windows.DataTemplate)。

  • 为什么第 2 版显示的内容与第 1 版不同?
  • 假设修复是微不足道的,出于个人喜好之外的任何原因,一种风格的版本是否会比另一种更可取?

  • 注意:我正在显示绑定(bind)和触发器,以防其中有影响内容的东西,但这只是样式的第一部分有所不同

    干杯,
    绿柱石

    样式 1

    显示:enter image description here
    <Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
        <Setter Property="Content" Value="a" />
        <Setter Property="Foreground" Value="Navy" />
        <Setter Property="FontFamily" Value="Wingdings 3" />
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="FontSize" Value="18" />
        <Setter Property="Width" Value="30" />
        <Setter Property="Height" Value="Auto" />
    
        <!--What makes it an Edit button-->
        <Setter Property="Command" Value="{Binding ActivateThisSatelliteVmCommand}"/>
        <Setter Property="ToolTip">
            <Setter.Value>
                <TextBlock>
                    <TextBlock.Text>
                        <Binding Path="HeaderLabel" StringFormat="{resx:Resx ResxName=Smack.Core.Presentation.Resources.MasterDetail, Key=Item_Edit_Label}"/>
                    </TextBlock.Text>
                </TextBlock>
            </Setter.Value>
        </Setter>
    
        <!-- WHen its available -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="theBorder" CornerRadius="4">
                        <ContentPresenter x:Name="theContent" VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter TargetName="theContent" Property="Visibility" Value="Hidden"/>
                            <Setter TargetName="theBorder" Property="Background" Value="Transparent"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="theBorder" Property="Background" Value="Orange"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    风格 2

    显示“System.Windows.DataTemplate”
    <Style x:Key="EditCommandButtonStyle" TargetType="{x:Type Button}" >
        <Setter Property="Content">
            <Setter.Value>
                <DataTemplate>
                    <TextBlock Text="a" FontFamily="Wingdings 3" FontWeight="Bold" FontSize="18" Foreground="Navy" />
                </DataTemplate>
            </Setter.Value>
        </Setter>
    
        <!--What makes it an Edit button-->
        <Setter Property="Command" Value="{Binding ActivateThisSatelliteVmCommand}"/>
        <Setter Property="ToolTip">
            <Setter.Value>
                <TextBlock>
                    <TextBlock.Text>
                        <Binding Path="HeaderLabel" StringFormat="{resx:Resx ResxName=Core.Presentation.Resources.MasterDetail, Key=Item_Edit_Label}"/>
                    </TextBlock.Text>
                </TextBlock>
            </Setter.Value>
        </Setter>
    
        <!-- When its available -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="theBorder" CornerRadius="4">
                        <ContentPresenter x:Name="theContent" VerticalAlignment="Center" HorizontalAlignment="Center" />
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="False">
                            <Setter TargetName="theContent" Property="Visibility" Value="Hidden"/>
                            <Setter TargetName="theBorder" Property="Background" Value="Transparent"/>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                        </Trigger>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="theContent" Property="Visibility" Value="Visible"/>
                            <Setter TargetName="theBorder" Property="Background" Value="Orange"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    最佳答案

    您的 Content属性设置为 DataTemplateDataTemplates旨在与 Template 一起使用属性,而不是通过 Content 直接插入到 VisualTree 中属性(property)

    更改样式 setter 以设置 ContentTemplate而不是 Content它应该可以正常工作

    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="a" FontFamily="Wingdings 3" FontWeight="Bold" FontSize="18" Foreground="Navy" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
    

    至于你的第二个问题,我更喜欢第一个问题,因为它更简单,而且我认为它在可视树中可能包含更少的元素(我必须仔细检查)

    关于wpf - 通过 setter v ContentTemplate 设置内容样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11059944/

    相关文章:

    wpf - 相对 URI 路径无法正常工作

    c# - WPF Visual Studio 设计器中的错误

    c# - WPF MVVM TreeView 使用 HierarchicalDataTemplate 不更新

    data-binding - Polymerfire 查询 orderByChild 不工作

    c# - WPF - UI 未从命令更新

    wpf - 使用LINQ vs CollectionView过滤集合

    c# - WPF: ListView :使用 MVVM 模式在 ListView 项目上绑定(bind)双击事件

    c# - 将 RadioButton XAML 定位在内容的中心底部

    data-binding - 数据绑定(bind)到 Grails 中命令上的枚举

    c# - 如何从基类的 ObserveableCollection 中显示子类的属性?