Строка ListView частично окрашена шрифтом - PullRequest
0 голосов
/ 14 февраля 2019

У меня ListView выглядит так:

 <ListView  Name="myLV"  ItemsSource="{Binding myObservableCollection}" IsSynchronizedWithCurrentItem="True" >
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="v1" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding var1}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="v2" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding var2}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Header="v3" Width="150">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding var3}"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                </GridView>
            </ListView.View>
        </ListView>

Каждая строка будет иметь набор из трех строк, которые выглядят, например, так:

  • Строка 1: aa-bbbb-cc
  • Строка 2: ax-bbbb-cd
  • Строка 3: aa-bbbb-ce

Теперь я хочу отдельный цвет текста длятри строки частично на позиции, где они отличаются.В приведенном выше примере мне пришлось бы раскрасить вторую и десятую позиции каждой из трех строк.

Я понятия не имею, с чего начать эту задачу, потому что мне даже трудно отгадать эту проблему,Есть идеи?

1 Ответ

0 голосов
/ 14 февраля 2019

Вы можете создать пользовательский элемент управления, который разбивает текст на четыре части и позволяет независимо стилизовать их.Следующий пример элемента управления принимает текст в качестве входных данных и сохраняет детали в выделенных свойствах:

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}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...