DataGrid visualization doesn't work
I have created custom DataGrid that bound to a DataTable.
DataGrid may have more than 50 columns so I've enabled column
virtualization .
My model is something like this :
public class Book
{
public int Id { get; set; }
}
public class HistoricalBook : Book
{
public DateTime HistoricalPeriod { get; set; }
}
public class CriminalBook : Book
{
public string MainCharacter { get; set; }
}
This is how I fill DataTable
public class MainViewModel : ViewModelBase
{
private DataTable _table;
public DataTable Table
{
get { return _table; }
set
{
if (value == _table) return;
_table = value;
RaisePropertyChanged(() => Table);
}
}
public MainViewModel()
{
Initiate();
}
private void Initiate()
{
Table = new DataTable("BookTable");
for (int i = 0; i < 20; i++)
Table.Columns.Add(new DataColumn(String.Format("Column{0}",
i), typeof (Book)));
Table.Columns.Add(new DataColumn("B", typeof (Book)));
for (int j = 0; j <= 80; j++)
{
var books = new Book[20];
if (j == 0)
{
for (int i = 0; i < 20; i++)
books[i] = new HistoricalBook
{
Id = i,
HistoricalPeriod =
DateTime.Now.AddDays(i)
};
}
else
{
for (int i = 0; i < 20; i++)
books[i] = new CriminalBook
{
Id = i,
MainCharacter = string.Format("Name
{0}", i)
};
}
Table.Rows.Add(books);
}
}
}
Because I want to bind different classes to each row of my DataGrid I've
used custom DataGrid that selects DataTemplate using DataTemplateSelector
based on bounded object to cell.
public class MyDataGrid : DataGrid
{
public static readonly DependencyProperty CellTemplateSelectorProperty =
DependencyProperty.Register("Selector", typeof
(DataTemplateSelector), typeof (MyDataGrid), new
FrameworkPropertyMetadata(null));
public DataTemplateSelector CellTemplateSelector
{
get { return (DataTemplateSelector)
GetValue(CellTemplateSelectorProperty); }
set { SetValue(CellTemplateSelectorProperty, value); }
}
public static readonly DependencyProperty
CellEditTemplateSelectorProperty =
DependencyProperty.Register("EditSelector", typeof
(DataTemplateSelector), typeof (MyDataGrid), new
FrameworkPropertyMetadata(null));
public DataTemplateSelector CellEditTemplateSelector
{
get { return (DataTemplateSelector)
GetValue(CellEditTemplateSelectorProperty); }
set { SetValue(CellEditTemplateSelectorProperty, value); }
}
protected override void
OnAutoGeneratingColumn(DataGridAutoGeneratingColumnEventArgs e)
{
e.Cancel = true;
var column = new DataRowColumn(e.PropertyName) {Header =
e.Column.Header, CellTemplateSelector = CellTemplateSelector,
CellEditingTemplateSelector = CellEditTemplateSelector
};
Columns.Add(column);
}
}
public class DataRowColumn : DataGridTemplateColumn
{
public string ColumnName { get; private set; }
public DataRowColumn(string column)
{
ColumnName = column;
}
protected override FrameworkElement GenerateElement(DataGridCell cell,
object dataItem)
{
var row = dataItem as DataRowView;
if (row != null)
{
object item = row[ColumnName];
cell.DataContext = item;
FrameworkElement element = base.GenerateElement(cell, item);
return element;
}
return new FrameworkElement();
}
}
XAML :
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.Resources>
<helper:BookTemplateSelector x:Key="bookTemplateSelector">
<helper:BookTemplateSelector.CriminalBookTemplate>
<DataTemplate>
<Label Content="{Binding Id}"
Width="50" />
</DataTemplate>
</helper:BookTemplateSelector.CriminalBookTemplate>
<helper:BookTemplateSelector.HistoricalBookTemplate>
<DataTemplate>
<Label Content="{Binding HistoricalPeriod}"
Width="50" />
</DataTemplate>
</helper:BookTemplateSelector.HistoricalBookTemplate>
</helper:BookTemplateSelector>
<helper:BookTemplateSelector x:Key="editBookTemplateSelector">
<helper:BookTemplateSelector.CriminalBookTemplate>
<DataTemplate>
<TextBox Text="{Binding Id}"
Width="50" />
</DataTemplate>
</helper:BookTemplateSelector.CriminalBookTemplate>
<helper:BookTemplateSelector.HistoricalBookTemplate>
<DataTemplate>
<TextBox Text="{Binding HistoricalPeriod}"
Width="50" />
</DataTemplate>
</helper:BookTemplateSelector.HistoricalBookTemplate>
</helper:BookTemplateSelector>
</Grid.Resources>
<control:MyDataGrid Grid.Row="0"
HeadersVisibility="None"
ItemsSource="{Binding Table}"
AutoGenerateColumns="True"
CellTemplateSelector="{StaticResource
bookTemplateSelector}"
CellEditTemplateSelector="{StaticResource
editBookTemplateSelector}"
EnableColumnVirtualization="True"
EnableRowVirtualization="True"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Standard">
</control:MyDataGrid>
</Grid>
At first view DataGrid works fine :
After scrolling data doesn't show correctly :
Source code
No comments:
Post a Comment