文本匹配MVVM时更改TextBox BorderBrush的颜色

时间:2013-06-11 22:04:58

标签: c# wpf mvvm triggers

全部,我创建了一个DataGrid,上面有一个搜索框。当用户键入并在DataGrid中显示文本时,匹配单元格的背面颜色为橙色。我已经设法了,但是现在(回想一下)如果找不到 的文本,则想要将搜索TextBox的{​​{1}}更改为'红色'(否则默认为)。控件的XAML是

BorderBrush

<UserControl x:Class="ResourceStudio.Views.ResourceControl" 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:viewModels="clr-namespace:ResourceStudio.ViewModels" xmlns:dataAccess="clr-namespace:ResourceStudio.DataAccess" xmlns:controls="clr-namespace:ResourceStudio.Controls" mc:Ignorable="d"> <DockPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <TextBox DockPanel.Dock="Top" Name="searchBox" BorderBrush="#FF007ACC" BorderThickness="2"> <TextBox.Resources> <Style TargetType="{x:Type TextBox}"> <Style.Triggers> <Trigger Property="dataAccess:DataGridTextSearch.IsTextMatch" Value="False"> <Setter Property="BorderBrush" Value="Red" /> </Trigger> </Style.Triggers> </Style> </TextBox.Resources> </TextBox> <Grid DockPanel.Dock="Top"> <Border> <controls:ResourceDataGrid ItemsSource="{Binding Path=Resources}" dataAccess:DataGridTextSearch.SearchValue="{Binding ElementName=searchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}"> <controls:ResourceDataGrid.Columns> <DataGridTextColumn Header="KeyIndex" Binding="{Binding KeyIndex}" IsReadOnly="True"/> <DataGridTextColumn Header="FileName" Binding="{Binding FileName}" IsReadOnly="True"/> <DataGridTextColumn Header="ResourceName" Binding="{Binding ResourceName}" IsReadOnly="False"/> <controls:CollectionTextColumn Collection="ResourceStringList" Visibility="Collapsed"/> </controls:ResourceDataGrid.Columns> <controls:ResourceDataGrid.Resources> <dataAccess:SearchValueConverter x:Key="searchValueConverter"/> <Style TargetType="{x:Type DataGridCell}"> <Setter Property="dataAccess:DataGridTextSearch.IsTextMatch"> <Setter.Value> <MultiBinding Converter="{StaticResource searchValueConverter}"> <Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" /> <Binding RelativeSource="{RelativeSource Self}" Path="(dataAccess:DataGridTextSearch.SearchValue)" /> </MultiBinding> </Setter.Value> </Setter> <Style.Triggers> <Trigger Property="dataAccess:DataGridTextSearch.IsTextMatch" Value="True"> <Setter Property="Background" Value="Orange" /> </Trigger> </Style.Triggers> </Style> </controls:ResourceDataGrid.Resources> </controls:ResourceDataGrid> </Border> </Grid> </DockPanel> </UserControl> 的基本Trigger无效。 如何使用与TextBox相同的机制更改TextBox BorderBrush的颜色?

感谢您的时间。


编辑。管理DataGridDependencyProperty的类是

IConverter

1 个答案:

答案 0 :(得分:2)

好的,我找到了一种方法,可以为AttachedProperty

创建一个新的IsAnyTextMatch DataGrid

IMultiValueConverter我们传递DataGrid并将新的DataGrid IsAnyTextMatch属性设置为true(如果找到任何匹配项),并输入{{} 1}} SearchBox将重置为false

现在,您可以在TextBox上创建IsAnyTextMatch并将其设置为DataTrigger DataGrid以设置TextBox边框颜色。

这可能不是最有魅力的方式,但它不需要您再次迭代IsAnyTextMatch集合来设置DataGrid背景。

以下是基于我的回答的示例:Proper DataGrid search from TextBox in WPF using MVVM

代码:

TextBox

的Xaml:

namespace WpfApplication10
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        }

        public IEnumerable<TestClass> TestData
        {
            get
            {
                yield return new TestClass { Column1 = "Stack", Column2 = "Overflow" };
                yield return new TestClass { Column1 = "Is", Column2 = "An" };
                yield return new TestClass { Column1 = "Awesome", Column2 = "Resource" };
            }
        }
    }


    public static class DataGridTextSearch
    {
        public static readonly DependencyProperty SearchValueProperty =
            DependencyProperty.RegisterAttached("SearchValue", typeof(string), typeof(DataGridTextSearch),
                new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.Inherits, new PropertyChangedCallback(PropertyChangedCallback)));

        private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is DataGrid)
            {
                // serach text has changed, reset tag to false
                (d as DataGrid).SetValue(IsAnyTextMatchProperty, false);
            }
        }

        public static string GetSearchValue(DependencyObject obj)
        {
            return (string)obj.GetValue(SearchValueProperty);
        }

        public static void SetSearchValue(DependencyObject obj, string value)
        {
            obj.SetValue(SearchValueProperty, value);
        }


        public static readonly DependencyProperty IsTextMatchProperty =
            DependencyProperty.RegisterAttached("IsTextMatch", typeof(bool),
              typeof(DataGridTextSearch), new UIPropertyMetadata(false));

        public static bool GetIsTextMatch(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsTextMatchProperty);
        }

        public static void SetIsTextMatch(DependencyObject obj, bool value)
        {
            obj.SetValue(IsTextMatchProperty, value);
        }

        public static readonly DependencyProperty IsAnyTextMatchProperty =
         DependencyProperty.RegisterAttached("IsAnyTextMatch", typeof(bool),
           typeof(DataGridTextSearch), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Inherits));

        public static bool GetIsAnyTextMatch(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsAnyTextMatchProperty);
        }

        public static void SetIsAnyTextMatch(DependencyObject obj, bool value)
        {
            obj.SetValue(IsAnyTextMatchProperty, value);
        }
    }

    public class SearchValueConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            string cellText = values[0] == null ? String.Empty : values[0].ToString();
            string searchText = values[1] as String;
            var datagrid = values[2] as DataGrid;
            bool returnvalue = false;
            if (!string.IsNullOrEmpty(searchText) &&
                !string.IsNullOrEmpty(cellText))
            {
                returnvalue = cellText.ToLower().StartsWith(searchText.ToLower());
            }

            // we found a match so mark DataGrid tag to true for use on TextBox
            if (returnvalue)
            {
                datagrid.SetValue(DataGridTextSearch.IsAnyTextMatchProperty, true);
            }
            return returnvalue;
        }

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

结果:

enter image description here enter image description here