Выделите все текстовые блоки с одинаковым текстом - PullRequest
0 голосов
/ 17 января 2019

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

Это тот же эффект, что и в Visual Studio или notepad ++, если вы выбрали слово (все те же слова выделяются в окне редактора).

Это то, что я имею до сих пор:

class TestViewModel
{
    public string TextToMatch { get; set; }
}

public partial class Test : UserControl
{
    TestViewModel _viewModel;
    public Test()
    {
        _viewModel = new TestViewModel();
        DataContext = _viewModel;
        InitializeComponent();
    }

    private void Test_MouseEnter(object sender, MouseEventArgs e)
    {
        var text = ((TextBlock)sender).Text;
        _viewModel.TextToMatch = text;
    }

    private void Test_MouseLeave(object sender, MouseEventArgs e)
    {
        _viewModel.TextToMatch = "";
    }
}

Частичный XAML:

    <StackPanel>
        <TextBlock
            Name="Test1"
            Background="{Binding TextToMatch Converter={StaticResource converter}}"
            MouseEnter="Test_MouseEnter"
            MouseLeave="Test_MouseLeave">
            This matches
        </TextBlock>
        <TextBlock
            Name="Test2"
            Background="{Binding TextToMatch Converter={StaticResource converter}}"
            MouseEnter="Test_MouseEnter"
            MouseLeave="Test_MouseLeave">
            This matches
        </TextBlock>
        <TextBlock
            Name="Test3"
            Background="{Binding TextToMatch Converter={StaticResource converter}}"
            MouseEnter="Test_MouseEnter"
            MouseLeave="Test_MouseLeave">
            Some other text
        </TextBlock>
        <TextBlock
            Name="Test4"
            Background="{Binding TextToMatch Converter={StaticResource converter}}"
            MouseEnter="Test_MouseEnter"
            MouseLeave="Test_MouseLeave">
            This matches
        </TextBlock>
        <TextBlock
            Name="Test5"
            Background="{Binding TextToMatch Converter={StaticResource converter}}"
            MouseEnter="Test_MouseEnter"
            MouseLeave="Test_MouseLeave">
            Some other text
        </TextBlock>
    </StackPanel>

Что кажется ясным, так это то, что мне нужен конвертер значений для этих привязок Это не проблема; проблема заключается в том, как получить текущее текстовое значение каждого текстового блока в преобразователе значений, чтобы он мог выполнить необходимое сравнение текста и вывести правильный цвет фона.

Как бы я поступил так? Или есть лучший способ, о котором я не думал?

1 Ответ

0 голосов
/ 17 января 2019

Вам нужно IMultiValueConverter и MultiBinding для этого

Примечание : Возможно, вам придется настроить преобразователь так, чтобы он лучше соответствовал вашим потребностям

Вариант 1 :
Недостаток: Вы должны вернуть свой фон «по умолчанию» тоже

Преобразователь:

public class DistinctBrushMultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values.Distinct().Count() == 1)
        {
            return Brushes.Orange; //Brush you want for highlight 
        }

        return null; //Or your default Brush
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Использование:

<TextBlock
    Name="Test1"
    MouseEnter="Test_MouseEnter"
    MouseLeave="Test_MouseLeave">
    <TextBlock.Background>
        <MultiBinding Converter="{StaticResource DistinctBrushMultiValueConverter}">
            <Binding Path="TextToMatch" />
            <Binding RelativeSource="{RelativeSource Self}" Path="Text" />
        </MultiBinding>
    </TextBlock.Background>
    This matches
</TextBlock>

Вариант 2: Использование Trigger внутри Style

Преобразователь:

public class DistinctValuesMultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Distinct().Count() == 1;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Style:

<Style x:Key="HighlightTextBlockStyle" TargetType="{x:Type TextBlock}">
    <Style.Triggers>
        <DataTrigger Value="True">
            <DataTrigger.Binding>
                <MultiBinding Converter="{StaticResource DistinctValuesMultiValueConverter}">
                    <Binding Path="TextToMatch" />
                    <Binding Path="Text" RelativeSource="{RelativeSource Self}" />
                </MultiBinding>
            </DataTrigger.Binding>
            <DataTrigger.Setters>
                <Setter Property="Background" Value="Orange" />
            </DataTrigger.Setters>
        </DataTrigger>
    </Style.Triggers>
</Style>

Использование:

<TextBlock
    Name="Test1"
    MouseEnter="Test_MouseEnter"
    MouseLeave="Test_MouseLeave"
    Style="{StaticResource HighlightTextBlockStyle}">
    This matches
</TextBlock>

Вариант 3 (только для вашей информации): : Вы также можете использовать Behavior

...