Вы можете создать пользовательский элемент управления, который разбивает текст на четыре части и позволяет независимо стилизовать их.Следующий пример элемента управления принимает текст в качестве входных данных и сохраняет детали в выделенных свойствах:
public partial class MyFormattedTextControl : UserControl, INotifyPropertyChanged
{
public MyFormattedTextControl()
{
InitializeComponent();
stack.DataContext = this;
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
// Using a DependencyProperty as the backing store for Text. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(MyFormattedTextControl), new PropertyMetadata(null, OnTextPropertyChanged));
private static void OnTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctrl = (MyFormattedTextControl)d;
var t = (string)e.NewValue;
var regex = new Regex("(?<Part1>.)(?<Part2>.)(?<Part3>.{7})(?<Part4>.)");
var m = regex.Match(t);
if (!m.Success)
{
ctrl.Part1 = ctrl.Part2 = ctrl.Part3 = ctrl.Part4 = string.Empty;
}
else
{
ctrl.Part1 = m.Groups["Part1"].Value;
ctrl.Part2 = m.Groups["Part2"].Value;
ctrl.Part3 = m.Groups["Part3"].Value;
ctrl.Part4 = m.Groups["Part4"].Value;
}
}
private string part1;
public string Part1
{
get { return part1; }
set { part1 = value; OnPropertyChanged(); }
}
private string part2;
public string Part2
{
get { return part2; }
set { part2 = value; OnPropertyChanged(); }
}
private string part3;
public string Part3
{
get { return part3; }
set { part3 = value; OnPropertyChanged(); }
}
private string part4;
public string Part4
{
get { return part4; }
set { part4 = value; OnPropertyChanged(); }
}
private void OnPropertyChanged([CallerMemberName] string callerMember = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(callerMember));
}
public event PropertyChangedEventHandler PropertyChanged;
}
В файле XAML пользовательский элемент управления отображает детали в отдельных текстовых блоках, которые можно независимо стилизовать:
<StackPanel x:Name="stack" Orientation="Horizontal">
<TextBlock Text="{Binding Part1}" />
<TextBlock Text="{Binding Part2}" Foreground="Red" />
<TextBlock Text="{Binding Part3}" />
<TextBlock Text="{Binding Part4}" Foreground="Green" />
</StackPanel>
В вашем ListView вместо TextBlock используется пользовательский элемент управления:
<DataTemplate>
<local:MyFormattedTextControl Text="{Binding var1}" />
</DataTemplate>
Обновление: форматирование блоков на основе значений данных
предоставив шаблон со значениями строк, вы можете добавить другое свойство зависимости в пользовательский элемент управления:
public IEnumerable<bool> PartFlags
{
get { return (bool[])GetValue(PartFlagsProperty); }
set { SetValue(PartFlagsProperty, value); }
}
// Using a DependencyProperty as the backing store for PartFlags. This enables animation, styling, binding, etc...
public static readonly DependencyProperty PartFlagsProperty =
DependencyProperty.Register("PartFlags", typeof(bool[]), typeof(MyFormattedTextControl), new PropertyMetadata(new bool[] { false, false, false, false }));
Чтобы преобразовать bools в цвет, вы можете создать собственный преобразователь значений, например,
public class PartColorValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var b = value as bool[] ?? new bool[] { };
var i = System.Convert.ToInt32(parameter);
return b.ElementAtOrDefault(i) ? Brushes.Red : Brushes.Black;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Вы можете использовать этот преобразователь в пользовательском элементе управления, чтобы применить цвет к деталям:
<UserControl x:Class="MyWpfApp.MyFormattedTextControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MyWpfApp"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<local:PartColorValueConverter x:Key="partColorValueConv" />
</UserControl.Resources>
<StackPanel x:Name="stack" Orientation="Horizontal">
<TextBlock Text="{Binding Part1}" Foreground="{Binding PartFlags, Converter = {StaticResource partColorValueConv}, ConverterParameter=0}" />
<TextBlock Text="{Binding Part2}" Foreground="{Binding PartFlags, Converter = {StaticResource partColorValueConv}, ConverterParameter=1}" />
<TextBlock Text="{Binding Part3}" Foreground="{Binding PartFlags, Converter = {StaticResource partColorValueConv}, ConverterParameter=2}" />
<TextBlock Text="{Binding Part4}" Foreground="{Binding PartFlags, Converter = {StaticResource partColorValueConv}, ConverterParameter=3}" />
</StackPanel>
</UserControl>
Чтобы проверить, я добавил четвертое значение в кортеж, содержащий шаблон (в моем случае это случайно сгенерированный шаблон):
<local:MyFormattedTextControl Text="{Binding Item1}" PartFlags="{Binding Item4}" />