我的表单中有Datagrid和Text Box。Datagrid显示我库存中的现有项目。我使用文本框来搜索并将焦点设置为与我的文本框匹配的行。现在它在VirtualizingStackPanel.IsVirtualization="false"时运行良好,但速度非常慢,并且获得了大量RAM资源。这是我的代码。
public IEnumerable<Microsoft.Windows.Controls.DataGridRow> GetDataGridRows(Microsoft.Windows.Controls.DataGrid grid)
{
var itemsSource = grid.ItemsSource as IEnumerable;
if (null == itemsSource) yield return null;
foreach (var item in itemsSource)
{
var row = grid.ItemContainerGenerator.ContainerFromItem(item) as Microsoft.Windows.Controls.DataGridRow;
if (null != row) yield return row;
}
}
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
var row = GetDataGridRows(AssortDataGrid);
/// go through each row in the datagrid
foreach (Microsoft.Windows.Controls.DataGridRow r in row)
{
DataRowView rv = (DataRowView)r.Item;
// Get the state of what's in column 1 of the current row (in my case a string)
string t = rv.Row["Ассортимент"].ToString().ToLower();
if (t.StartsWith(SearchBoxDataGrid.Text.ToLower()))
{
AssortDataGrid.SelectedIndex = r.GetIndex();
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
我想要的是使它VirtualizingStackPanel。IsVirtualization="true",但在这种情况下,我的方法不起作用。我知道为什么它不起作用,我的代码只适用于显示Datagrid的一部分。你推荐什么?如何解决此问题?任何想法都将不胜感激。如果你给出任何工作代码,那将是非常棒的。我希望我能解释我的问题。
虚拟化意味着WPF将重用UI组件,并简单地替换组件后面的DataContext
。
例如,如果您的网格有1000个项目,而只有10个可见,则它将只渲染大约14个UI项目(滚动缓冲区的额外项目),而滚动只是替换这些UI项目后面的DataContext
,而不是为每个项目创建新的UI元素。如果不使用Virtualization
,它将创建所有1000个UI项。
为了使Search
使用病毒化,您需要循环通过DataContext
(DataGrid.Items
),而不是通过UI组件。这可以在代码后面完成,也可以在使用MVVM时在ViewModel
中处理SeachCommand
。
我做了一些编码并使其工作。如果将来有人需要,请使用它。首先,我正在创建产品列表
List<string> ProductList;
然后在加载方法中,我将所有的产品都列在我的产品列表中。
SqlCommand commProc2 = new SqlCommand("SELECT dbo.fGetProductNameFromId(ProductID) as ProductName from Assortment order by ProductName desc", MainWindow.conn);
string str2;
SqlDataReader dr2 = commProc2.ExecuteReader();
ProductList = new List<string>();
try
{
if (dr2.HasRows)
{
while (dr2.Read())
{
str2 = (string)dr2["ProductName"];
ProductList.Insert(0, str2.ToLower ());
}
}
}
catch (Exception ex)
{
MessageBox.Show("An error occured while trying to fetch datan" + ex.Message);
}
dr2.Close();
dr2.Dispose();
之后,我在SearchBoxDataGrid_TextChanged 中做了一些更改
private void SearchBoxDataGrid_TextChanged(object sender, TextChangedEventArgs e)
{
int pos = 0;
string typedString = SearchBoxDataGrid.Text.ToLower();
foreach (string item in ProductList)
{
if (!string.IsNullOrEmpty(SearchBoxDataGrid.Text))
{
if (item.StartsWith(typedString))
{
pos = ProductList.IndexOf(item);
AssortDataGrid.SelectedIndex = pos;
AssortDataGrid.ScrollIntoView(AssortDataGrid.SelectedItem);
break;
}
}
}
}
现在它在VirtualizingStackPanel.IsVirtualization="true"时工作。仅此而已。