Eu tenho um costume ControlTemplate
com duplo ContentPresenter
s. O modelo é aplicado a um Label
. Quando eu definir "Polvo aleatório"(apenas texto) como Conteúdo do rótulo, funciona exatamente como o esperado. Quando eu definir "<TextBlock> Polvo aleatório </TextBlock>"como o Conteúdo, não funciona (apenas um ContentPresenter é representado visualmente). Eu uso o seguinte código para reproduzir o comportamento:
<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>
E aqui você pode ver como fica:
http://i56.tinypic.com/1zgdull.png
eu pensei quando você insere apenas texto na propriedade Content, ele é encapsulado por TextBlock, então por que exatamente o visual do segundo Labelrepresentação diferente da primeira? E como fazer o segundo Label se comportar corretamente (torná-lo parecido com o primeiro Label, mas apenas modificando o modelo)? Obrigado!
Respostas:
1 para resposta № 1A diferença é ...
- Quando você define uma string como Conteúdo para um
Label
, umaTextBlock
é gerado para a string em cadaContentPresenter
. - Quando você define um
TextBlock
diretamente comoContent
paraLabel
, vai acabar onde você tem oContentPresenter
, mas como você só tem umTextBlock
, só pode estar em um lugar de cada vez.
Atualizar
<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();
}
}
3 para resposta № 2
O problema subjacente aqui é que você está tentando colocar um visual (o TextBlock
) em dois lugares diferentes ao mesmo tempo. Um visual só pode ter um único pai, portanto, um dos apresentadores de conteúdo "ganha" e o outro não tem nenhum conteúdo.
Se tudo o que você deseja fazer é ter uma cópia visual do TextBlock
então use um VisualBrush
.