Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>If you only want to highlight the cells with the text from the <code>TextBox</code> you could make an <code>AttatchedProperty</code> for the <code>DataGrid</code> to accept your search value from the <code>TextBox</code> and create another <code>AttatchedProperty</code> for the <code>Cell</code> to indicate a match that you can usee to set properties in the <code>Cell</code> style. Then we create a <code>IMultiValueConverter</code> to check the <code>Cell</code> value for a match to the search <code>Text</code>.</p> <p>This way its reusable on other projects as you only need the <code>AttachedProperties</code> and <code>Converter</code></p> <p>Bind the <code>AttachedProperty</code> <code>SearchValue</code> to your <code>TextBox</code> <code>Text</code> property.</p> <pre><code> &lt;DataGrid local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" </code></pre> <p>Then create a <code>Style</code> for <code>DataGridCell</code> and create a Setter for the <code>AttachedProperty</code> <code>IsTextMatch</code> using the <code>IMultiValueConverter</code> to return if the cells text matches the <code>SearchValue</code></p> <pre><code>&lt;Setter Property="local:DataGridTextSearch.IsTextMatch"&gt; &lt;Setter.Value&gt; &lt;MultiBinding Converter="{StaticResource SearchValueConverter}"&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" /&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" /&gt; &lt;/MultiBinding&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; </code></pre> <p>Then we can use the <code>Cells</code> attached <code>IsTextMatch</code> property to set a highlight using a <code>Trigger</code></p> <pre><code>&lt;Style.Triggers&gt; &lt;Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True"&gt; &lt;Setter Property="Background" Value="Orange" /&gt; &lt;/Trigger&gt; &lt;/Style.Triggers&gt; </code></pre> <h2>Here is a working example showing my rambilings :)</h2> <p>Code:</p> <pre><code>namespace WpfApplication17 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); for (int i = 0; i &lt; 20; i++) { TestData.Add(new TestClass { MyProperty = GetRandomText(), MyProperty2 = GetRandomText(), MyProperty3 = GetRandomText() }); } } private string GetRandomText() { return System.IO.Path.GetFileNameWithoutExtension(System.IO.Path.GetRandomFileName()); } private ObservableCollection&lt;TestClass&gt; _testData = new ObservableCollection&lt;TestClass&gt;(); public ObservableCollection&lt;TestClass&gt; TestData { get { return _testData; } set { _testData = value; } } } public class TestClass { public string MyProperty { get; set; } public string MyProperty2 { get; set; } public string MyProperty3 { get; set; } } public static class DataGridTextSearch { // Using a DependencyProperty as the backing store for SearchValue. This enables animation, styling, binding, etc... 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); } // Using a DependencyProperty as the backing store for IsTextMatch. This enables animation, styling, binding, etc... 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, System.Globalization.CultureInfo culture) { string cellText = values[0] == null ? string.Empty : values[0].ToString(); string searchText = values[1] as string; if (!string.IsNullOrEmpty(searchText) &amp;&amp; !string.IsNullOrEmpty(cellText)) { return cellText.ToLower().StartsWith(searchText.ToLower()); } return false; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) { return null; } } } </code></pre> <p>Xaml:</p> <pre><code>&lt;Window x:Class="WpfApplication17.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication17" Title="MainWindow" Height="350" Width="525" Name="UI"&gt; &lt;StackPanel DataContext="{Binding ElementName=UI}"&gt; &lt;TextBox Name="SearchBox" /&gt; &lt;DataGrid x:Name="grid" local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding TestData}" &gt; &lt;DataGrid.Resources&gt; &lt;local:SearchValueConverter x:Key="SearchValueConverter" /&gt; &lt;Style TargetType="{x:Type DataGridCell}"&gt; &lt;Setter Property="local:DataGridTextSearch.IsTextMatch"&gt; &lt;Setter.Value&gt; &lt;MultiBinding Converter="{StaticResource SearchValueConverter}"&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" /&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" /&gt; &lt;/MultiBinding&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;Style.Triggers&gt; &lt;Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True"&gt; &lt;Setter Property="Background" Value="Orange" /&gt; &lt;/Trigger&gt; &lt;/Style.Triggers&gt; &lt;/Style&gt; &lt;/DataGrid.Resources&gt; &lt;/DataGrid&gt; &lt;/StackPanel&gt; &lt;/Window&gt; </code></pre> <p>Result:</p> <p><img src="https://i.stack.imgur.com/B1OYL.png" alt="enter image description here"> <img src="https://i.stack.imgur.com/NVERO.png" alt="enter image description here"></p> <h2>Edit:</h2> <p>If you just want to select the row based on a single Column you can modify quite easily :).</p> <p>Override the Style of <code>DataGridRow</code> instead of <code>DataGridCell</code>.</p> <pre><code> &lt;Style TargetType="{x:Type DataGridRow}"&gt; </code></pre> <p>First pass in the property you want into the <code>IMultiValueConverter</code> this should be your <code>DataContext</code></p> <pre><code>&lt;MultiBinding Converter="{StaticResource SearchValueConverter}"&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="DataContext.MyProperty" /&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" /&gt; &lt;/MultiBinding&gt; </code></pre> <p>Then change the <code>Trigger</code> to set <code>IsSelected</code> on the <code>Row</code></p> <pre><code>&lt;Style.Triggers&gt; &lt;Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True"&gt; &lt;Setter Property="IsSelected" Value="True" /&gt; &lt;/Trigger&gt; &lt;/Style.Triggers&gt; </code></pre> <p>Should look like this: </p> <pre><code> &lt;DataGrid x:Name="grid" local:DataGridTextSearch.SearchValue="{Binding ElementName=SearchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding TestData}" &gt; &lt;DataGrid.Resources&gt; &lt;local:SearchValueConverter x:Key="SearchValueConverter" /&gt; &lt;Style TargetType="{x:Type DataGridRow}"&gt; &lt;Setter Property="local:DataGridTextSearch.IsTextMatch"&gt; &lt;Setter.Value&gt; &lt;MultiBinding Converter="{StaticResource SearchValueConverter}"&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="DataContext.MyProperty" /&gt; &lt;Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" /&gt; &lt;/MultiBinding&gt; &lt;/Setter.Value&gt; &lt;/Setter&gt; &lt;Style.Triggers&gt; &lt;Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True"&gt; &lt;Setter Property="IsSelected" Value="True" /&gt; &lt;/Trigger&gt; &lt;/Style.Triggers&gt; &lt;/Style&gt; &lt;/DataGrid.Resources&gt; &lt;/DataGrid&gt; </code></pre> <p>Result:</p> <p><img src="https://i.stack.imgur.com/hIGZ3.png" alt="enter image description here"></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload