这是第二中方法,可直接绑定,我这里只是做出了一种思路,并不是最完美。
这里注意一下,因为我里面引用了MVVMLight,所以可能代码不是复制过去就能用了的。
样式也是,所以复制过去看不是我贴出来的界面这也不奇怪。代码:
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal"> <Button Content="新增列" Command="{Binding AddColumnCmd}" Margin="5"/> <Button Content="删除列" Command="{Binding DeleteColumnCmd}" Margin="5"/> <Button Content="新增数据" Command="{Binding AddDataCmd}" Margin="5"/> </StackPanel> <!-- 自定义的DataGrid,使用到了一个依赖属性DataSource --> <Controls:DyDataGrid HeadersVisibility="All" RowHeaderWidth="60" Grid.Row="1" MinColumnWidth="10" DataSource="{Binding DyDGrid,Source={StaticResource Locator}}" SelectionUnit="CellOrRowHeader" SelectionMode="Extended"/> </Grid>
自定义控件DyDataGrid,就添加一个依赖属性,赋值一个VM类DyDataGridViewModel,把DyDataGrid赋值给DyDataGridViewModel的DataGrid
public class DyDataGrid : DataGrid { public DyDataGrid() : base() { AutoGenerateColumns = false; CanUserAddRows = false; CanUserSortColumns = false; } // 这个控件的一个自定义属性; private DyDataGridViewModel mDataSource; public DyDataGridViewModel DataSource { get { return mDataSource; } set { mDataSource = value; } } /// <summary> /// 定义了一个名为DataSourc的控件依赖属性; /// 这个依赖属性用于显示peopoleDataGrid的内容; /// </summary> public static readonly DependencyProperty DataSourceProperty = DependencyProperty.Register("DataSource", typeof(DyDataGridViewModel), typeof(DyDataGrid), new FrameworkPropertyMetadata(new PropertyChangedCallback(OnDataSourcePeopertyChanged))); private static void OnDataSourcePeopertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { DyDataGrid dyDataGrid = (DyDataGrid)obj; if (args.NewValue is DyDataGridViewModel) { if (dyDataGrid != null) { DyDataGridViewModel peoplesViewModel = args.NewValue as DyDataGridViewModel; peoplesViewModel.DDataGrid = dyDataGrid; } } }
/// <summary> /// DyDataGrid的数据源,自动新增列等功能 /// </summary> public class DyDataGridViewModel : ViewModelBase { /// <summary> /// 绑定的数据 /// </summary> ObservableCollection<ExpandoObject> _Items = new ObservableCollection<ExpandoObject>(); private DataGrid _DDataGrid; public DataGrid DDataGrid { get { return _DDataGrid; } set { if (_DDataGrid != null) { _DDataGrid.ItemsSource = null; } _DDataGrid = value; Init(); } } public ObservableCollection<ExpandoObject> Items { get { return _Items; } set { _Items = value; RaisePropertyChanged(() => Items); } } #region 方法 /// <summary> /// 初始化 /// </summary> public void Init() { Items.Clear(); for (int i = 0; i < 5; i++) { dynamic item = new ExpandoObject(); item.A = "Property A value - " + i.ToString(); item.B = "Property B value - " + i.ToString(); _Items.Add(item); } DDataGrid.Columns.Add(new DataGridTextColumn() { Header = "A", Binding = new Binding("A") }); DDataGrid.Columns.Add(new DataGridTextColumn() { Header = "B", Binding = new Binding("B") }); _DDataGrid.ItemsSource = Items; } public void AddData() { //dynamic item = new ExpandoObject(); //item.A = "New Item - A"; //item.B = "New Item - B"; //item.NewColumn1 = "New Item - C"; //Items.Add(item); } /// <summary> /// 添加列和列数据 /// </summary> /// <param name="columnName">列名</param> /// <param name="columnName">显示列名</param> /// <param name="vs">填充的列数据</param> public void AddColumn(string columnName, string Header, List<string> vs) { int i = 0; int count = vs.Count; //循环获取行数据 foreach (IDictionary<String, Object> item in Items) { //每行添加新列数据 item.Add(columnName, vs[i]); i++; //添加完数据跳出 if (i >= vs.Count) break; } //如果列数据多,则继续添加 for (; i < vs.Count; i++) { //可以这么用 columnName就是传进来的列名 dynamic item = new ExpandoObject(); item.columnName = vs[i]; Items.Add(item); } //添加列 DDataGrid.Columns.Add(new DataGridTextColumn() { Header = Header, Binding = new Binding(columnName) }); } /// <summary> /// 删除选中列 /// </summary> public void DeleteColumn() { for (int i = 0; i < DDataGrid.SelectedCells.Count; i++) { //DataRowView Row = (DataRowView)DDataGrid.SelectedCells[i].Item; //string result = Row[DDataGrid.SelectedCells[i].Column.DisplayIndex].ToString(); //string result = DDataGrid.SelectedCells[i].Column.DisplayIndex.ToString(); DDataGrid.Columns.Remove(DDataGrid.SelectedCells[i].Column); } } #endregion }
public class W1ViewModel : ViewModelBase { /// <summary> /// Initializes a new instance of the MainViewModel class. DataGrid /// </summary> public W1ViewModel(DyDataGridViewModel dyDataGridViewModel) { DyDGrid = dyDataGridViewModel; } public DyDataGridViewModel DyDGrid; public RelayCommand AddColumnCmd => new Lazy<RelayCommand>(() => new RelayCommand(AddColumn)).Value; public RelayCommand AddDataCmd => new Lazy<RelayCommand>(() => new RelayCommand(AddData)).Value; public RelayCommand DeleteColumnCmd => new Lazy<RelayCommand>(() => new RelayCommand(DeleteColumn)).Value; private void AddData() { DyDGrid.AddData(); } int newColumnIndex = 1; private void AddColumn() { string cName = "C" + newColumnIndex; List<string> vs = new List<string>(); for (int i = 0; i < newColumnIndex; i++) { vs.Add("New Item - D" + i); } DyDGrid.AddColumn(cName, cName + "Show", vs); newColumnIndex++; } private void DeleteColumn() { DyDGrid.DeleteColumn(); } }
DyDataGridViewModel封装了对DataGrid的操作,同时也是DataGrid的数据源,可以使用绑定更新
效果如下:
链接: https://pan.baidu.com/s/1eDRHMUzvpQyTjnmqoscpKw 提取码: txs6
想了想,还是把整个代码发上来,哈哈,感觉你们应该喜欢。