2

すべて、DataGrid上に検索ボックスがある を作成しました。ユーザーが入力し、テキストがDataGrid背面に表示されると、一致するセルの色がオレンジ色になります。私はこれを管理しましたが、テキストが見つからない場合は検索を「赤」TextBoxに変更したいと考えています(それ以外の場合はデフォルト)。コントロールの 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>

私の基本は何もTriggerTextBoxません。に使用したのと同じメカニズムを使用しての色を変更するにはどうすればよいですか?TextBox BorderBrushDataGrid

御時間ありがとうございます。


編集。DependencyPropertyIConverterを支配するクラス

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

    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 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;
        if (!string.IsNullOrEmpty(searchText) && 
            !string.IsNullOrEmpty(cellText))
        {
            return cellText.ToLower().StartsWith(searchText.ToLower());
        }
        return false;
    }

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

1 に答える 1

2

OK、私はこれを行う方法を見つけましAttachedProperty IsAnyTextMatchDataGrid

IMultiValueConverterを渡し、 一致するものが見つかった場合DataGridは新しいプロパティを true に設定し、を入力すると false にリセットされますDataGrid IsAnyTextMatchSearchBoxIsAnyTextMatch

これで、TextBox にを作成し、DataTriggerそれをDataGrid IsAnyTextMatchに設定して、TextBox の境界線の色を設定できます。

これはこれを行うための最も魅力的な方法ではないかもしれませんが、背景DataGridを設定するためだけにコレクションを繰り返し処理する必要はありません。TextBox

ここでの私の答えに基づく例を次に示します: MVVM を使用した WPF の TextBox からの適切な DataGrid 検索

コード:

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();
        }
    }
}

Xaml:

<Window x:Class="WpfApplication10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="188" Width="288" Name="UI" xmlns:local="clr-namespace:WpfApplication10">

    <StackPanel DataContext="{Binding ElementName=UI}">
        <TextBox Name="SearchBox" BorderThickness="3" >
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Setter Property="BorderBrush" Value="Blue" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding (local:DataGridTextSearch.IsAnyTextMatch), ElementName=dataGrid}" Value="false">
                            <Setter Property="BorderBrush" Value="Red" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
        <DataGrid x:Name="dataGrid" 
                  local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" 
                  local:DataGridTextSearch.IsAnyTextMatch="False"
                  ItemsSource="{Binding TestData}" >
            <DataGrid.Resources>
                <local:SearchValueConverter x:Key="SearchValueConverter" />
                <Style TargetType="{x:Type DataGridCell}">
                    <Setter Property="local:DataGridTextSearch.IsTextMatch">
                        <Setter.Value>
                            <MultiBinding Converter="{StaticResource SearchValueConverter}">
                                <Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
                                <Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
                                <Binding ElementName="dataGrid" />
                                <!-- pass in datarid-->
                            </MultiBinding>
                        </Setter.Value>
                    </Setter>
                    <Style.Triggers>
                        <Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
                            <Setter Property="Background" Value="Orange" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </DataGrid.Resources>
        </DataGrid>
    </StackPanel>
</Window>

結果:

ここに画像の説明を入力 ここに画像の説明を入力

于 2013-06-12T00:19:08.467 に答える