I want to use the GridView to display a set of data in WPF. The data will have the information, in which columns it should be shown. The Class looks like that:
public class RowViewModel : ViewModelBase
{
public string RowName { get; set; }
public object CellObject { get; set; }
public int ColumnIndex { get; set; }
public string ColumnHeader { get; set; }
public string CellText { get; set; }
}
That means, i have some rows, but i don't know how many columns i have. And i can't binding the properties in RowViewModel in my GridView, because the columns, in which the DisplayText should be shown, will always be different.
The GridView should looks like that:
Column1 Column2 Columns3 ... ColumnN NewColumn
Row1 Text1
Row2 Text2
Row3 Text3
Row4 Text4
...
NewRow NewText
If there is a Row5, whose ColumnIndex greater than ColumnN, a new column should be added.
How can i implemente the GridView to show the RowViewModels dynamically?
I have tried to convert all the rows to a standard format to satisfy the GridView, but that will not be good, if i want to add a row with new ColumnIndex after initialized the GridView.
I tried to use Dependency Properties. But i can't display the text with binding in correct columns.
public static class RadGridViewDependencyProperties
{
#region ConfigurableColumns
//RadGridView.Columns ist readonly
public static readonly DependencyProperty ConfigurableColumnsProperty =
DependencyProperty.RegisterAttached(
"ConfigurableColumns",
typeof(object),
typeof(RadGridViewDependencyProperties),
new PropertyMetadata(null, ConfigurableColumnsPropertyChangedCallback));
private static void ConfigurableColumnsPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var radGridView = dependencyObject as RadGridView;
var gridViewColumnCollection = radGridView == null ? null : dependencyPropertyChangedEventArgs.NewValue as GridViewColumnCollection;
if (gridViewColumnCollection == null)
{
return;
}
radGridView.Columns.Clear();
radGridView.Columns.AddRange(gridViewColumnCollection);
}
public static void SetConfigurableColumns(DependencyObject dependencyObject, object value)
{
var radGridView = dependencyObject as RadGridView;
var columns = radGridView == null ? null : value as GridViewColumnCollection;
if (columns == null)
{
return;
}
radGridView.SetValue(ConfigurableColumnsProperty, columns);
}
public static GridViewColumnCollection GetConfigurableColumns(DependencyObject dependencyObject)
{
var radGridView = dependencyObject as RadGridView;
return radGridView == null ? null : (GridViewColumnCollection)radGridView.GetValue(ConfigurableColumnsProperty);
}
#endregion
}
And i used a configurator to initilize the columns:
public class GridViewDataColumnConfigurator
{
private readonly GridViewColumnCollection _columns;
private readonly ObservableCollection<RowViewModel> _rowViewModelCollection;
public GridViewDataColumnConfigurator(ObservableCollection<RowViewModel> rowViewModelCollection)
{
_columns = new GridViewColumnCollection();
_rowViewModelCollection = rowViewModelCollection;
}
public GridViewColumnCollection Columns
{
get
{
_columns.Clear();
var firstRow = _rowViewModelCollection != null ? _rowViewModelCollection.FirstOrDefault() : null;
if (firstRow != null)
{
var gridViewDataColumn = new GridViewDataColumn
{
IsVisible = true,
IsReadOnly = true,
Header = "",
DataMemberBinding = new Binding("RowName")
};
_columns.Add(gridViewDataColumn);
}
else
{
return _columns;
}
foreach (var rowViewModel in _rowViewModelCollection)
{
if (_columns[rowViewModel.ColumnHeader] == null)
{
var gridViewDataColumn = new GridViewDataColumn
{
IsVisible = true,
DisplayIndex = rowViewModel.ColumnIndex,
UniqueName = rowViewModel.ColumnHeader,
Header = rowViewModel.ColumnHeader
};
gridViewDataColumn.DataMemberBinding = new Binding(".")
{
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Converter = new RowViewModelCellTextConverter(),
ConverterParameter = gridViewDataColumn.DisplayIndex
};
gridViewDataColumn.IsReadOnlyBinding = new Binding(".")
{
Mode = BindingMode.OneWay,
Converter = new RowViewModelCellReadOnlyConverter(),
ConverterParameter = gridViewDataColumn.DisplayIndex
};
_columns.Add(gridViewDataColumn);
}
}
return _columns;
}
}
public class RowViewModelCellTextConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is RowViewModel) || !(parameter is int))
{
return null;
}
var rowViewModel = value as RowViewModel;
return rowViewModel.ColumnIndex == (int)parameter ? rowViewModel.CellText : null;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return value;
}
}
public class RowViewModelCellReadOnlyConverter : IValueConverter
{
public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (!(value is RowViewModel) || !(parameter is int))
{
return null;
}
var rowViewModel = value as RowViewModel;
return rowViewModel.ColumnIndex != (int)parameter;
}
public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
}
Any help will be great, thanks a lot!