我正在使用wpf datagrid顯示大量數據(大約100列和1000行)。這些列綁定到使用typedescripter動態添加的屬性。默認情況下,datagrid會顯示所有列,但我們添加的功能允許用戶僅查看所有列的子集,並且還可以更改顯示列的順序。我目前通過切換列的可見性屬性並更改其顯示索引來實現此目的。然而,這樣做的表現真的很糟糕。在大型wpf數據網格中移動/隱藏列的性能問題
下面是一個例子來重現問題
的XAML看起來很直截了當
<Window x:Class="WpfDataGridTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Height="Auto" Margin="5">
<CheckBox x:Name="ApplyColumns" Width="200" Margin="5" Checked="CheckBox_Checked" Unchecked="CheckBox_Checked">Show Predefined Columns</CheckBox>
</StackPanel>
<DataGrid
x:Name="Grid" EnableColumnVirtualization="False"
EnableRowVirtualization="False"
Grid.Row="1" SelectionUnit="Cell"
ItemsSource="{Binding MyDataView}">
</DataGrid>
</Grid>
後面的代碼如下所示
public partial class MainWindow : Window
{
/// <summary>
/// this dictionary stores the column name of columns to display and their displayIndex
/// </summary>
Dictionary<string,int> _predefinedColumns=new Dictionary<string, int>()
{
{"Column_8",0},
{"Column_9",1},
{"Column_11",2},
{"Column_14",3},
{"Column_12",4},
{"Column_34",5},
{"Column_78",6},
{"Column_54",7},
{"Column_88",8},
{"Column_98",9},
{"Column_90",10},
{"Column_51",11},
{"Column_100",12},
{"Column_35",13},
{"Column_112",14},
{"Column_101",15}
};
public MainWindow()
{
InitializeComponent();
DataContext = new MyClassViewModel();
}
/// <summary>
/// Toggle display of only subset of columns
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
if (ApplyColumns.IsChecked ?? false)
{
foreach (var col in this.Grid.Columns)
{
if (_predefinedColumns.ContainsKey(col.Header as string))
{
col.Visibility = Visibility.Visible;
col.DisplayIndex = _predefinedColumns[col.Header as string];
}
else
{
col.Visibility = Visibility.Collapsed;
}
}
}
else
{
foreach (var col in this.Grid.Columns)
{
col.Visibility = Visibility.Visible;
var header = col.Header.ToString();
col.DisplayIndex = Int32.Parse(header.Substring(7)) - 1;
}
}
}
}
此視圖模型再現大數據使用手動創建的DataTable。然而,在數據網格背後的實際代碼綁定與動態屬性類使用typedescripter
public class MyClassViewModel
{
public DataView MyDataView
{
get
{
var dt = new DataTable();
foreach (var colNum in Enumerable.Range(1, 120))
{
dt.Columns.Add(String.Format("Column_{0}", colNum), Type.GetType("System.Int32"));
}
var r = new Random();
for (int x = 1; x <= 1000; x++)
{
var dr = dt.NewRow();
foreach (var colNum in Enumerable.Range(1, 120))
{
dr[String.Format("Column_{0}", colNum)] = r.Next(100);
}
dt.Rows.Add(dr);
}
return dt.DefaultView;
}
}
}
我曾嘗試以下,但到目前爲止
1.性能更好,如果我把行和列的虛擬化沒有運氣加入。但是,這會破壞不可接受的滾動性能(特別是如果您嘗試拖動拇指)。
2.除了更改顯示和可見性之外,我嘗試刪除所有列,然後僅添加所需的列,但它對性能也沒有影響。
我真的很感謝任何幫助。我們不希望以不利的滾動性能爲代價來提高性能。所以如果需要開啓虛擬化,我們應該如何改進滾動性能。或者有更好的方式來實現良好的滾動性能和良好的性能列顯示/隱藏/移動這樣大的數據網格。
誰將在同一時間看到1000行?每頁至少25-100 ...你必須考慮減少行數量和問題消失。 –
感謝您的建議。實際上,我們也可以選擇頁面行,但業務設計還需要一個選項,讓用戶可以查看並比較所有行(窗口通常橫跨兩個顯示器,以便可以看到很多行) – shomat
我有同樣的問題,做過你發現任何解決方法? –