突出显示具有相同文本的所有文本块

Highlight all text blocks that have the same text

我有一个包含多个文本块的相当复杂的表单。我想为这些块添加一个绑定,这样当鼠标悬停在它们上面时,所有其他文本与我悬停的 运行 相匹配的块都会突出显示。

这与您在 Visual Studio 或 notepad++ 中看到的效果相同,如果您选择了一个词(所有相同的词都会在编辑器中突出显示 window)。

这是我目前拥有的:

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>

似乎很清楚,我需要一个用于这些绑定的值转换器。那不是问题;问题是如何获取每个文本块的当前文本值到值转换器,以便它可以执行必要的文本比较并输出正确的背景颜色。

我该怎么做?还是有什么我没有想到的更好的方法?

为此

你需要一个IMultiValueConverter and a MultiBinding

注意:您可能需要调整转换器以更好地满足您的需求

选项 1:
缺点:你也必须 return 你的 "default" 背景

转换器:

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:Style

中使用 Trigger

转换器:

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 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