我正在研究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
集合,并将其列分别绑定到IsChecked
和Text
。
注意,为了简单起见,我在DataRowViewModel
中省略了INPC
的实现。这将工作,但如果你要改变数据行属性从视图模型的代码,你应该实现INPC
。