I have a performance issue with the WPF DataGrid (.net 4.0)
first, some details:
- I have a datagrid with an Observable collection as ItemsSource.
- this observableCollection itself contains collections of objects, each collection hence being a row, each object being a cell ("logical" cell of course, not actual dataGridCell)
the reason why I do this is because I only know at runtime how many columns I will have in my dataGrid.
- then I bind each DataGridCell's value to the value of the object in the "logical" table (= the collection of collections)
now the trouble I have is that I also have to be able to change whatever cell's Properties (like Background, Foreground, FontFamily, etc...) at any time while the app is running.
The solution I came up with is one involving setting the columns' cellStyles with bindings that bind to the "logical" cells' properties
here Is a sample code (no Xaml in my app):
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Width = 1200;
Height = 780;
Top = 60;
Left = 200;
DataGrid dg = new DataGrid();
Content = dg;
ObservableCollection<Row> Source = new ObservableCollection<Row>();
dg.ItemsSource = Source;
dg.SelectionMode = DataGridSelectionMode.Extended;
dg.IsSynchronizedWithCurrentItem = true;
dg.CanUserSortColumns = false;
dg.CanUserReorderColumns = true;
dg.CanUserResizeColumns = true;
dg.CanUserResizeRows = true;
dg.CanUserAddRows = false;
dg.CanUserDeleteRows = false;
dg.AutoGenerateColumns = false;
dg.EnableColumnVirtualization = true;
dg.EnableRowVirtualization = false; // unuseful in my case : I alawys have less lines than the DG can contain
dg.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
dg.GridLinesVisibility = DataGridGridLinesVisibility.None;
dg.HorizontalGridLinesBrush = Brushes.LightGray;
dg.MinRowHeight = 20;
dg.RowHeaderWidth = 20;
for (int i = 0; i < 100; i++)
{
DataGridTextColumn column = new DataGridTextColumn();
column.Binding = new Binding(String.Format(CultureInfo.InvariantCulture, "[{0}].Text", i));
Style style = new Style(typeof(DataGridCell));
style.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new Binding(String.Format(CultureInfo.InvariantCulture, "[{0}].Background", i))));
style.Setters.Add(new Setter(DataGridCell.ForegroundProperty, new Binding(String.Format(CultureInfo.InvariantCulture, "[{0}].Foreground", i))));
column.CellStyle = style;
column.Header = "Column " + i;
dg.Columns.Add(column);
}
for (int i = 0; i < 35; i++)
{
Row dgRow = new Row();
Source.Add(dgRow);
for (int j = 0; j < 100; j++)
dgRow.Add(new TextBox() { Text = "cell " + i + "/" + j, Background = Brushes.AliceBlue, Foreground = Brushes.BlueViolet });
}
}
}
public class Row : ObservableCollection<TextBox>
{
}
my problem is: with the VolumnVirtualisation On (I don't need row Virtualization in my case), the grid takes about 2sec to load, and then 1sec each time I move the horizontal scrollbar by a big leap (clic in the scrollBar bg, not the arrow)
this is too much for my purpose
so my question is: am I doing something wrong and if yes, what? what better way to do this do I have?
thanks for reading