通过setter v ContentTemplate设置样式内容

时间:2012-06-16 01:04:44

标签: wpf xaml data-binding mvvm styles

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

  1. 为什么第二个版本不会显示与第一个相同的内容?
  2. 假设修复是微不足道的,那么除了个人喜好之外,还有一种版本的风格比其他版本更合适吗?
  3. 注意:我正在显示绑定和触发器,以防有影响内容的内容,但它只是样式的第一部分变化

    干杯,
    Berryl

    样式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>
    

2 个答案:

答案 0 :(得分:15)

您的Content媒体资源已设为DataTemplate

DataTemplates旨在与Template属性一起使用,而不是通过Content属性

直接插入到VisualTree中

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

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

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

答案 1 :(得分:0)

我找到了解决此问题的另一种方法:

private
  Edits: TList<TEdit>;

procedure TfrmGenerateExam.FormCreate(Sender: TObject);
begin
  Edits := TList<TEdit>.Create;
end;

procedure TfrmGenerateExam.FormDestroy(Sender: TObject);
begin
  Edits.Free;
end;

function TfrmGenerateExam.FillScrollBox;
var
  Panel: TPanel;
  Edit: TEdit;
begin
  ...
  Panel := TPanel.Create(Self);
  Panel.Parent := ScrollBox1;
  ...
  Edit := TEdit.Create(Panel);
  Edit.Parent := Panel;
  ...
  Edits.Add(Edit);
  ...
end;

function TfrmGenerateExam.zlicz_liczby: Integer;
var
  i: integer;
begin
  Result := 0;
  for i := 0 to Edits.Count - 1 do
    Result := Result + StrToInt(Edits[i].Text);
end;