WPF MVVM动态添加带有两个控件的行到Grid/DataGrid



我正在研究mvvm,并面对动态添加的这个问题-在简单的win表单中,我已经很容易地用一个循环和少量规范来完成DataRow。因此,任务是-将字符串列表中的所有元素放入Grid/DataGrid,其中包含两列-第一列用于复选框,第二列用于基于字符串的控件。我认为最好的办法是使用DataGrid。因此,我用这个DataGrid和按钮创建了一个wpf对话框,并为ViewModel创建了一个单独的文件。现在我的ViewModel类包含一个字符串列表。我卡住了……我读过一些ObservableCollection<UIElement>必须持有DataGridRow(?? ?)在我的情况下有两个控件…

编辑:我正在尝试<DataGridCheckBoxColumn复选框和<DataGridTemplateColumn控制。现在的问题是将这两列与字符串列表绑定-将字符串的值传递给控件,然后就行了。我需要用ObservableCollection吗?

当我使用mvvm在wpf中绑定数据网格时,而不是将其视为行和列的集合,我将其视为对象的集合-每一行代表一个单独的对象,每一列代表该对象的一个属性。所以在你的情况下,你应该做一个类来代表你在网格中显示的东西,它将有一个布尔值和一个字符串属性(在你所述的2列中使用)。

public class MyListItem : ImplementPropertyChangedStuff
{
    private string _myString;
    private bool _myBool;
    public MyListItem()
    { }
    public string MyStringProperty
    {
        get { return _myString; }
        set
        {
            _myString = value;
            this.RaisePropertyChanged("MyStringProperty");
        }
    }
    public bool MyBoolProperty
    {
        get { return _myBool; }
        set
        {
            _myBool = value;
            this.RaisePropertyChanged("MyBoolProperty");
        }
    }
}

现在,在您的视图模型中,您可以使用单个列表,而不是为每个列使用单独的列表。如果你想添加/删除/编辑行,那么你应该使用可观察集合,因为它内置了propertychanged的东西,当对集合进行任何更改时,它会更新ui。

public class MyViewModel
{
   private ObservableCollection<MyListItem> _items;
   public ObservableCollection<MyListItem> Items
    {
        get { return _items; }
        set
        {
            _items = value;
            this.RaisePropertyChanged("Items");
        }
    }
 public MyViewModel()
 {
    this.Items = new ObservableCollection<MyListItem>();
    this.LoadMyItems();
 }
 public void LoadMyItems()
 {
    this.Items.Add(new MyListItem { MyBoolProperty = true, MyStringProperty = "Hello" };
 }
}
最后是DataGrid绑定:
<DataGrid ItemsSource="{Binding Path=Items, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridCheckBoxColumn Header="MyBoolProperty" Binding="{Binding Path=MyBoolProperty}"
    <DataGridTextColumn Header="MyStringProperty" Binding="{Binding Path=MyStringProperty"/>
  </DataGrid.Columns>
</DataGrid>

数据行需要一个视图模型。像这样:

public class DataRowViewModel
{
    public bool? IsChecked { get; set; }
    public string Text { get; set; }
}

然后,对话框的视图模型应该显示List<DataRowViewModel>而不是List<string>,或者,如果你计划从代码中修改这个列表,ObservableCollection<DataRowViewModel>:

public class DialogViewModel
{
    // other code here
    public ObservableCollection<DataRowViewModel> DataRows
    {
        get { return dataRows ?? (dataRows = new ObservableCollection<DataRowViewModel>(yourStringList.Select(s => new DataRowViewModel { Text = s }))); }
    }
    private ObservableCollection<DataRowViewModel> dataRows;
}

接下来,设置DataGrid绑定到DataRows集合,并将其列分别绑定到IsCheckedText

注意,为了简单起见,我在DataRowViewModel中省略了INPC的实现。这将工作,但如果你要改变数据行属性从视图模型的代码,你应该实现INPC

最新更新