在Label的内容中明确使用TextBlock使得ContentPresenter表现得很奇怪

时间:2011-02-27 16:34:47

标签: .net wpf templates xaml label

我有一个带有ControlTemplateContentPresenter的自定义Label。该模板已应用于<Window x:Class="WeirdTextBlock.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Window.Resources> <Style TargetType="Label"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Label"> <Border BorderBrush="Red" BorderThickness="1" Padding="2"> <Grid> <ContentPresenter /> <ContentPresenter Margin="2,2,0,0" /> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid Margin="20" HorizontalAlignment="Left"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="20" /> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <Label Grid.Row="0"> Random octopus </Label> <Label Grid.Row="2"> <TextBlock>Random octopus</TextBlock> </Label> </Grid> </Window> 。当我将“ Random octopus ”(只是文本)设置为Label的内容时,它的工作方式完全符合预期。当我将“&lt; TextBlock&gt; Random octopus&lt; / TextBlock&gt; ”设置为内容时,它不起作用(只能在视觉上表示一个ContentPresenter)。我使用以下代码重现行为:

{{1}}

在这里你可以看到它的样子:

http://i56.tinypic.com/1zgdull.png

我想when you enter just text into Content property, it gets wrapped by TextBlock,那么为什么第二个Label的视觉表现与第一个不同呢?以及如何使第二个Label正常运行(使其看起来像第一个Label,但只能通过修改模板)?谢谢!

2 个答案:

答案 0 :(得分:3)

这里的根本问题是你试图将视觉(TextBlock)同时放在两个不同的地方。视觉效果只能有一个父母,因此其中一个内容主持人“获胜”而另一个内容没有任何内容。

如果您只想拥有TextBlock的直观副本,请使用VisualBrush

答案 1 :(得分:1)

区别在于......

  • 当您将字符串设置为Label的内容时,会为每个TextBlock的字符串生成ContentPresenter
  • 当您为TextBlock直接设置Content作为Label时,它会在您拥有ContentPresenter的位置结束,但由于您只有一个TextBlock },它一次只能在一个地方。

更新

<Style TargetType="Label">
    <Style.Resources>
        <local:TypeOfConverter x:Key="TypeOfConverter"/>
        <Style TargetType="TextBlock">
            <Setter Property="Background" Value="Transparent"/>
        </Style>
    </Style.Resources>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Label">
                <Border BorderBrush="Red" BorderThickness="1" Padding="2">
                    <Grid>
                        <ContentPresenter Name="content" Grid.ZIndex="2"/>
                        <ContentPresenter Name="secondContent" Grid.ZIndex="1" Margin="2,2,0,0" Visibility="Collapsed"/>
                        <Border Grid.ZIndex="1">
                            <Border.RenderTransform>
                                <TranslateTransform X="2" Y="2"/>
                            </Border.RenderTransform>
                            <Border.Background>
                                <VisualBrush Visual="{Binding ElementName=content, Path=Content}"/>
                            </Border.Background>
                        </Border>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},
                                                   Path=Content,
                                                   Converter={StaticResource TypeOfConverter}}"
                                 Value="{x:Type sys:String}">
                        <Setter TargetName="secondContent" Property="Visibility" Value="Visible"/>
                    </DataTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<强> TypeOfConverter

public class TypeOfConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return (value == null) ? null : value.GetType();
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}