我想使用GridView在WPF中显示一组数据。数据将包含信息,应在哪些列中显示。该类看起来像这样:
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; }
}
这意味着,我有一些行,但我不知道我有多少列。我无法在我的GridView中绑定RowViewModel中的属性,因为应该显示DisplayText的列将始终不同。
GridView看起来应该是这样的:
Column1 Column2 Columns3 ... ColumnN NewColumn
Row1 Text1
Row2 Text2
Row3 Text3
Row4 Text4
...
NewRow NewText
如果Row5的ColumnIndex大于ColumnN,则应添加新列。
如何实现GridView动态显示RowViewModels?
我试图将所有行转换为标准格式以满足GridView,但是如果我想在初始化GridView后添加一个带有新ColumnIndex的行,那就不太好了。
我尝试使用依赖属性。但我无法在正确的列中显示带有绑定的文本。
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
}
我使用配置程序来初始化列:
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;
}
}
}
任何帮助都会很棒,非常感谢!