The challenge with
virtualization enabled is that there aren't actual DataGridRowItems created for
all data available, so the control cannot find across all the data.
To get around that limitation, the code below creates a collection of
Run objects based on the data in your collection. RapidFindReplace can
search invisible Run objects, and when the user clicks the 'next' or 'previous'
arrow buttons, the code will select the appropriate row.
Please note that the code below does not do 'all
occurrence highlighting'. In other words the user must click
next/previous to highlight the rows.
Please press CTRL-F when the Window loads to activate the Find dialog.
XAML
<Window
x:Class="SearchVisualTree.DataGrid_Virtualization"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:RapidFindReplace="clr-namespace:Keyoti.RapidFindReplace.WPF;assembly=Keyoti4.RapidFindReplace.WPF"
xmlns:local="clr-namespace:SearchVisualTree"
Title="DataGrid_Virtualization"
Height="547.687" Width="468.683">
<Grid>
<RapidFindReplace:RapidFindReplacePopupControl
HorizontalAlignment="Left" Height="0"
VerticalAlignment="Top" Width="0"
Name="Finder"/>
<DataGrid
HorizontalAlignment="Left" Margin="10,10,0,0"
VerticalAlignment="Top" Height="498" Width="441"
Name="dataGrid" >
</DataGrid>
</Grid>
</Window>
CODEBEHIND
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace SearchVisualTree
{
/// <summary>
/// Interaction logic for
DataGrid_Virtualization.xaml
/// </summary>
public partial class
DataGrid_Virtualization : Window
{
Customers customers;
public
DataGrid_Virtualization()
{
InitializeComponent();
//create data
customers = new Customers();
customers.Add(new Customer() { FirstName = "Andy" });
customers.Add(new Customer() { FirstName = "Bob" });
customers.Add(new Customer() { FirstName = "Caroline" });
customers.Add(new Customer() { FirstName = "Dennis" });
customers.Add(new Customer() { FirstName = "Emma" });
customers.Add(new Customer() { FirstName = "Fred" });
customers.Add(new Customer() { FirstName = "Georgia" });
customers.Add(new Customer() { FirstName = "Hannah" });
customers.Add(new Customer() { FirstName = "Ian" });
customers.Add(new Customer() { FirstName = "Jen" });
customers.Add(new Customer() { FirstName = "Kevin" });
customers.Add(new Customer() { FirstName = "Louise" });
customers.Add(new Customer() { FirstName = "Marcus" });
customers.Add(new Customer() { FirstName = "Nora" });
customers.Add(new Customer() { FirstName = "Oliver" });
customers.Add(new Customer() { FirstName = "Patsy" });
customers.Add(new Customer() { FirstName = "Quentin" });
customers.Add(new Customer() { FirstName = "Rachael" });
customers.Add(new Customer() { FirstName = "Steve" });
customers.Add(new Customer() { FirstName = "Terri" });
customers.Add(new Customer() { FirstName = "Andy" });
customers.Add(new Customer() { FirstName = "Bob" });
customers.Add(new Customer() { FirstName = "Caroline" });
customers.Add(new Customer() { FirstName = "Dennis" });
customers.Add(new Customer() { FirstName = "Emma" });
customers.Add(new Customer() { FirstName = "Fred" });
customers.Add(new Customer() { FirstName = "Georgia" });
customers.Add(new Customer() { FirstName = "Hannah" });
customers.Add(new Customer() { FirstName = "Ian" });
customers.Add(new Customer() { FirstName = "Jen" });
customers.Add(new Customer() { FirstName = "Kevin" });
customers.Add(new Customer() { FirstName = "Louise" });
customers.Add(new Customer() { FirstName = "Marcus" });
customers.Add(new Customer() { FirstName = "Nora" });
customers.Add(new Customer() { FirstName = "Oliver" });
customers.Add(new Customer() { FirstName = "Patsy" });
customers.Add(new Customer() { FirstName = "Quentin" });
customers.Add(new Customer() { FirstName = "Rachael" });
customers.Add(new Customer() { FirstName = "Steve" });
customers.Add(new Customer() { FirstName = "Terri" });
//bind
data
Binding
bind = new Binding();
bind.Source = customers;
dataGrid.SetBinding(DataGrid.ItemsSourceProperty, bind);
//create a Run collection of grid data, this will be searched instead of visual
controls.
List<Run>
runs = new List<Run>();
foreach (Customer customer in customers)
{
runs.Add(new EntityRun<Customer>(customer, customer.FirstName));
}
//create a 'findable' container
Keyoti.RapidFindReplace.WPF.FindHandlers.RunCollectionContainer
container = new
Keyoti.RapidFindReplace.WPF.FindHandlers.RunCollectionContainer(runs);
//setup the container as what to search within
Finder.FindScope = container;
//Listen to changes to the "CurrentMatch" property, when these
changes occur we need to select and scroll to the CurrentMatch in the grid.
System.ComponentModel.DependencyPropertyDescriptor dpd =
System.ComponentModel.DependencyPropertyDescriptor.FromProperty
(Keyoti.RapidFindReplace.WPF.RapidFindReplacePopupControl.CurrentMatchProperty,
typeof(Keyoti.RapidFindReplace.WPF.RapidFindReplacePopupControl));
dpd.AddValueChanged(Finder, new EventHandler(delegate(object sender2, EventArgs
e2)
{
//If there is a match, select it and scroll to it.
if ((sender2 as
Keyoti.RapidFindReplace.WPF.RapidFindReplacePopupControl).CurrentMatch != null)
{
dataGrid.SelectedItem = (((sender2 as
Keyoti.RapidFindReplace.WPF.RapidFindReplacePopupControl).CurrentMatch.Run as
EntityRun<Customer>).Entity);
dataGrid.ScrollIntoView(dataGrid.SelectedItem);
}
}));
Loaded
+= delegate
{
Finder.PART_RapidFindReplaceControl.FinishedSearching += delegate
{
MessageBox.Show(this, "No more matches");
};
};
}
public class
Customers : System.Collections.ObjectModel.ObservableCollection<Customer>
{
}
public class
Customer
{
public
string FirstName { get; set; }
}
class
EntityRun<T> : Run
{
T
entity;
public
T Entity
{
get { return entity; }
}
public
EntityRun(T c, string toSearch)
: base(toSearch)
{
entity = c;
}
}
}
}
In this example the entity is type Customer,
this can be easily modified to your class. You will see the use of the
generic type EntityRun<Customer>, just change it to your type,
eg EntityRun<MyEntity>
|