当虚拟化堆栈面板时,如何在文本框和数据网格中找到匹配的单词.IsVirtualizing= "true"?



我的表单中有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使用病毒化,您需要循环通过DataContextDataGrid.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"时工作。仅此而已。

最新更新