C# WPF:将形状插入 TextBlock
C# WPF: Insert Shape Into TextBlock
我想在 WPF 中将彩色方块(带边框)插入到 TextBlock
中。正方形的颜色需要动态设置,因此理想情况下这应该发生在代码隐藏中,而不是 XAML.
我猜最好的方法是使用 InlineUIContainer
,但我不知道如何放置 Rectangle
使其与文本对齐,并且大小适合字体大小。
到目前为止我有:
Color myColor = GetMyColor();
TextBlock textBlock = new TextBlock();
textBlock.Inlines.Add(new Run("My color: "));
// Attempt with a Canvas and Rectangle
Canvas canvas = new Canvas();
canvas.Children.Add(new Rectangle() { Height = 6, Width = 6, Fill = new SolidColorBrush(color.Value) });
textBlock.Inlines.Add(new InlineUIContainer(canvas));
// Hacky version that looks terrible
textBlock.Inlines.Add(new Run(" ") { Background = new SolidColorBrush(myColor) });
这里的问题是 Rectangle
是从文本基线创建的,垂下。我希望它相对于文本、正方形(即纵横比为 1)垂直居中,并且理想情况下自动调整为字体大小。
我想知道 Viewbox
是否有用,或者 VerticalAlignment
属性的某种组合,但我无法使它们起作用。任何建议将不胜感激。
根据您想要的方块大小,您可以尝试使用 unicode 字符 0x25A0 或 0x25AA。
这是在 Xaml 中定义的示例,但您也可以在代码隐藏中实现相同的效果。
<TextBlock FontFamily="Segoe UI">
<Run Text="ABC" />
<Run Foreground="Red" Text="■" />
<Run Foreground="Green" Text="▪" />
</TextBlock>
<TextBlock FontFamily="Tahoma">
<Run Text="ABC" />
<Run Foreground="Red" Text="■" />
<Run Foreground="Green" Text="▪" />
</TextBlock>
请注意,与常规字母的高度相比,不同的字体系列以不同的比例呈现这些字符。
您可以使用 ContentControl
和 DataTemplate
。
UserControl
或自定义 Control
或 ContentControl
也是一个很好的解决方案,特别是如果您想添加一个行为。
以下示例使用 ContentControl
和 DataTemplate
在文本旁边显示一个居中的 Rectangle
,其中形状的颜色和文本是动态值。形状的大小是相对于 FontSize
应用于 ContentControl
.
可以通过在 Viewbox
上设置 Margin
或将 IValueConverter
附加到 Viewbox
的 Height
绑定来调整形状的最终大小:
MainWindow.xaml
<Window>
<Window.Resources>
<DataTemplate x:Key="DataModelTemplate"
DataType="{x:Type DataModel}">
<DockPanel HorizontalAlignment="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=HorizontalContentAlignment}">
<TextBlock x:Name="TextLabel"
FontSize="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=FontSize}"
Text="{Binding TextValue}"
VerticalAlignment="Center" />
<Viewbox Height="{Binding ElementName=TextLabel, Path=ActualHeight}"
Margin="8"
Stretch="Uniform">
<Rectangle Width="10"
Height="10"
Fill="{Binding Color}" />
</Viewbox>
</DockPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ContentControl x:Name="TextControl1"
ContentTemplate="{StaticResource DataModelTemplate}"
FontSize="50" />
<ContentControl x:Name="TextControl2"
ContentTemplate="{StaticResource DataModelTemplate}"
FontSize="20" />
</StackPanel>
</Window>
MainWindow.xaml.cs
partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.TextControl1.Content = new DataModel("@Test 1", Brushes.Yellow);
this.TextControl2.Content = new DataModel("@Test 2", Brushes.Red);
}
}
DataModel.cs
class DataModel : INotifyPropertyChanged
{
public DataModel(string textValue, Brush color)
{
this.TextValue = textValue;
this.Color = color;
}
public string TextValue { get; }
public Brush Color { get; }
}
我想在 WPF 中将彩色方块(带边框)插入到 TextBlock
中。正方形的颜色需要动态设置,因此理想情况下这应该发生在代码隐藏中,而不是 XAML.
我猜最好的方法是使用 InlineUIContainer
,但我不知道如何放置 Rectangle
使其与文本对齐,并且大小适合字体大小。
到目前为止我有:
Color myColor = GetMyColor();
TextBlock textBlock = new TextBlock();
textBlock.Inlines.Add(new Run("My color: "));
// Attempt with a Canvas and Rectangle
Canvas canvas = new Canvas();
canvas.Children.Add(new Rectangle() { Height = 6, Width = 6, Fill = new SolidColorBrush(color.Value) });
textBlock.Inlines.Add(new InlineUIContainer(canvas));
// Hacky version that looks terrible
textBlock.Inlines.Add(new Run(" ") { Background = new SolidColorBrush(myColor) });
这里的问题是 Rectangle
是从文本基线创建的,垂下。我希望它相对于文本、正方形(即纵横比为 1)垂直居中,并且理想情况下自动调整为字体大小。
我想知道 Viewbox
是否有用,或者 VerticalAlignment
属性的某种组合,但我无法使它们起作用。任何建议将不胜感激。
根据您想要的方块大小,您可以尝试使用 unicode 字符 0x25A0 或 0x25AA。
这是在 Xaml 中定义的示例,但您也可以在代码隐藏中实现相同的效果。
<TextBlock FontFamily="Segoe UI">
<Run Text="ABC" />
<Run Foreground="Red" Text="■" />
<Run Foreground="Green" Text="▪" />
</TextBlock>
<TextBlock FontFamily="Tahoma">
<Run Text="ABC" />
<Run Foreground="Red" Text="■" />
<Run Foreground="Green" Text="▪" />
</TextBlock>
请注意,与常规字母的高度相比,不同的字体系列以不同的比例呈现这些字符。
您可以使用 ContentControl
和 DataTemplate
。
UserControl
或自定义 Control
或 ContentControl
也是一个很好的解决方案,特别是如果您想添加一个行为。
以下示例使用 ContentControl
和 DataTemplate
在文本旁边显示一个居中的 Rectangle
,其中形状的颜色和文本是动态值。形状的大小是相对于 FontSize
应用于 ContentControl
.
可以通过在 Viewbox
上设置 Margin
或将 IValueConverter
附加到 Viewbox
的 Height
绑定来调整形状的最终大小:
MainWindow.xaml
<Window>
<Window.Resources>
<DataTemplate x:Key="DataModelTemplate"
DataType="{x:Type DataModel}">
<DockPanel HorizontalAlignment="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=HorizontalContentAlignment}">
<TextBlock x:Name="TextLabel"
FontSize="{Binding RelativeSource={RelativeSource AncestorType=ContentControl}, Path=FontSize}"
Text="{Binding TextValue}"
VerticalAlignment="Center" />
<Viewbox Height="{Binding ElementName=TextLabel, Path=ActualHeight}"
Margin="8"
Stretch="Uniform">
<Rectangle Width="10"
Height="10"
Fill="{Binding Color}" />
</Viewbox>
</DockPanel>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ContentControl x:Name="TextControl1"
ContentTemplate="{StaticResource DataModelTemplate}"
FontSize="50" />
<ContentControl x:Name="TextControl2"
ContentTemplate="{StaticResource DataModelTemplate}"
FontSize="20" />
</StackPanel>
</Window>
MainWindow.xaml.cs
partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.TextControl1.Content = new DataModel("@Test 1", Brushes.Yellow);
this.TextControl2.Content = new DataModel("@Test 2", Brushes.Red);
}
}
DataModel.cs
class DataModel : INotifyPropertyChanged
{
public DataModel(string textValue, Brush color)
{
this.TextValue = textValue;
this.Color = color;
}
public string TextValue { get; }
public Brush Color { get; }
}