Hi,
I have made a dynamic grid which is populated by a viewmodel 'DynamicGridViewModel'
In my view in code-behind I create the columns for the view. Because the value-type I am binding to is a generic type, I also set the DataType for the columns in code-behind.
This is working fine until I try to use the default interactive sorting and filtering functions on the grid. When I click on a header, the arrow that is shown when a column is sorted appears, however the data is not sorted. When I click the filter-button in the column-header, the distinct values aren't present in the filter-view and when I apply a custom filter, the data is not filtered.
I suspect it has something to do with the data-type. Do I have to set another property for the column? I compared with a gridview that is binding to a string-property and the only difference I can find is that with the generic type, the ItemPropertyInfo is not set (but I can't change it in my example because it is read-only.
Can you help me on this matter please?
Kind regards,
Dieter
I have made a dynamic grid which is populated by a viewmodel 'DynamicGridViewModel'
public
class
DynamicGridViewModel: BaseViewModel
{
public
DynamicGridViewModel(Func<DetailedObservableCollection<DynamicGridColumnViewModel>> getColumns,
Action getData)
{
GetColumns = getColumns;
GetData = getData;
Columns = GetColumns();
}
private
readonly
Func<DetailedObservableCollection<DynamicGridColumnViewModel>> GetColumns;
public
Action GetData;
public
void
SetColumns()
{
GetColumns();
if
(Columns.Any(dynamicGridColumnViewModel => dynamicGridColumnViewModel.IsFixedColumn
&& Columns.IndexOf(dynamicGridColumnViewModel) > 0
&& !Columns[Columns.IndexOf(dynamicGridColumnViewModel) - 1].IsFixedColumn))
{
throw
new
Exception(
"Fixed (frozen) columns should appear on the beginning of the grid"
);
}
}
private
DetailedObservableCollection<DynamicGridColumnViewModel> _columns;
public
DetailedObservableCollection<DynamicGridColumnViewModel> Columns
{
get
{
return
_columns; }
set
{
if
(value != _columns)
{
_columns = value;
RaisePropertyChanged(() => Columns);
}
}
}
private
DetailedObservableCollection<DynamicGridRowViewModel> _rows =
new
DetailedObservableCollection<DynamicGridRowViewModel>();
public
DetailedObservableCollection<DynamicGridRowViewModel> Rows
{
get
{
return
_rows; }
set
{
if
(value != _rows)
{
_rows = value;
RaisePropertyChanged(() => Rows);
}
}
}
}
public
abstract
class
DynamicGridColumnViewModel : BaseViewModel
{
private
string
_header;
public
string
Header
{
get
{
return
_header; }
set
{
if
(value != _header)
{
_header = value;
RaisePropertyChanged(() => Header);
}
}
}
private
bool
_isFixedColumn;
public
bool
IsFixedColumn
{
get
{
return
_isFixedColumn; }
set
{
if
(value != _isFixedColumn)
{
_isFixedColumn = value;
RaisePropertyChanged(() => IsFixedColumn);
}
}
}
public
abstract
Type GetColumnValuesType();
}
}
[DebuggerDisplay(
"{Header}"
)]
public
class
DynamicGridColumnViewModel<T> : DynamicGridColumnViewModel
{
public
override
Type GetColumnValuesType()
{
return
typeof
(T);
}
}
public
class
DynamicGridRowViewModel: BaseViewModel
{
public
DynamicGridRowViewModel()
{
Cells=
new
DetailedObservableCollection<DynamicGridCellViewModel>();
}
public
DetailedObservableCollection<DynamicGridCellViewModel> Cells {
get
;
private
set
; }
}
[DebuggerDisplay(
"{Value}"
)]
public
class
DynamicGridCellViewModel : BaseViewModel
{
}
[DebuggerDisplay(
"{Value}"
)]
public
class
DynamicGridCellViewModel<T> : DynamicGridCellViewModel
{
public
DynamicGridCellViewModel(T value)
{
Value = value;
}
private
T _value;
public
T Value
{
get
{
return
_value; }
private
set
{
if
(!value.Equals(_value))
{
_value = value;
RaisePropertyChanged(() => Value);
}
}
}
}
In my view in code-behind I create the columns for the view. Because the value-type I am binding to is a generic type, I also set the DataType for the columns in code-behind.
public
partial
class
OverzichtView: UserControl
{
public
OverzichtView()
{
InitializeComponent();
Loaded += OverzichtViewLoaded;
}
private
void
OverzichtViewLoaded(
object
sender, RoutedEventArgs e)
{
BuildColumns();
var vm = OverzichtGridView.DataContext
as
DynamicGridViewModel;
if
(vm !=
null
)
vm.GetData();
}
private
void
BuildColumns()
{
var vm = OverzichtGridView.DataContext
as
DynamicGridViewModel;
OverzichtGridView.Columns.Clear();
OverzichtGridView.FrozenColumnCount = 0;
if
(vm !=
null
)
{
OverzichtGridView.ItemsSource = vm.Rows;
foreach
(var column
in
vm.Columns)
{
var gridColumn =
new
GridViewDataColumn();
gridColumn.Header = column.Header;
gridColumn.DataMemberBinding =
new
Binding
{
Path =
new
PropertyPath(
"Cells["
+ vm.Columns.IndexOf(column) +
"].Value"
),
Mode = BindingMode.TwoWay
};
gridColumn.DataType = column.GetColumnValuesType();
OverzichtGridView.Columns.Add(gridColumn);
if
(column.IsFixedColumn)
OverzichtGridView.FrozenColumnCount++;
}
}
}
}
This is working fine until I try to use the default interactive sorting and filtering functions on the grid. When I click on a header, the arrow that is shown when a column is sorted appears, however the data is not sorted. When I click the filter-button in the column-header, the distinct values aren't present in the filter-view and when I apply a custom filter, the data is not filtered.
I suspect it has something to do with the data-type. Do I have to set another property for the column? I compared with a gridview that is binding to a string-property and the only difference I can find is that with the generic type, the ItemPropertyInfo is not set (but I can't change it in my example because it is read-only.
Can you help me on this matter please?
Kind regards,
Dieter