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

时间:2019-01-17 17:56:03

标签: c# wpf mvvm data-binding valueconverter

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

如果您选择一个单词(所有相同的单词都在编辑器窗口中突出显示),则与在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 :(得分:1)

为此您需要一个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 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