0

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!

Ivan
  • 81
  • 2
  • 11
  • take a look at http://stackoverflow.com/questions/9000549/how-can-i-dynamically-add-a-rowdefinition-to-a-grid-in-an-itemspaneltemplate it might give you some idea – Bizhan Mar 04 '14 at 09:05
  • I have tried to use dependency properties to show the DisplayText. But i still can't display the text with binding in correct columns. I have update my question. – Ivan Mar 04 '14 at 14:21

0 Answers0