0

我的表单中有数据网格和文本框。Datagrid 正在向我显示我的库存中的现有项目。我使用文本框搜索并将焦点设置到与我的文本框匹配的那一行。现在它在 VirtualizingStackPanel.IsVirtualizing="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.IsVirtualizing="true" 但在这种情况下我的方法不起作用。我知道为什么它不起作用,我的代码仅适用于显示 Datagrid 的一部分。你有什么建议吗?如何解决这个问题?任何想法将不胜感激。如果您提供任何工作代码,那就太棒了。我希望我能解释我的问题。

4

2 回答 2

0

虚拟化意味着 WPF 将重用 UI 组件,并简单地替换掉DataContext后面的组件。

例如,如果您的 Grid 有 1000 个项目并且只有 10 个是可见的,它只会渲染大约 14 个 UI 项目(滚动缓冲区的额外项目),并且滚动只是替换DataContext这些 UI 项目后面,而不是为每个项目创建新的 UI 元素。如果您不使用Virtualization,它将创建所有 1000 个 UI 项。

为了Search使用虚拟化,您需要循环通过DataContext( DataGrid.Items) 而不是通过 UI 组件。这可以在代码隐藏中完成,或者如果您使用 MVVM,您可以SeachCommandViewModel.

于 2012-08-27T12:47:20.143 回答
0

我做了一些编码并使它工作。如果有人将来需要它,请使用它。首先,我正在创建产品列表

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 data\n" + 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.IsVirtualizing="true" 时工作。就这些。

于 2012-09-05T12:14:01.513 回答