你好我正在构建一个带有数据网格的 wpf 应用程序,模式是模型视图视图模型。
我的所有屏幕都包含一个内容控件,我只是为他分配了具有合适数据模板的视图模型,
无论如何,我的问题是组合框列,数据上下文是呈现的实体,我需要它作为视图模型。
什么是最好的解决方案?
你好我正在构建一个带有数据网格的 wpf 应用程序,模式是模型视图视图模型。
我的所有屏幕都包含一个内容控件,我只是为他分配了具有合适数据模板的视图模型,
无论如何,我的问题是组合框列,数据上下文是呈现的实体,我需要它作为视图模型。
什么是最好的解决方案?
我正在使用另一个数据网格,但它可能是相似的。我这样做的方式是这样的:
在 XAML 中,我在资源中定义了一个 ObjectDataProvider:
<ObjectDataProvider x:Key="VM" ObjectInstance="{x:Null}" x:Name="vm"/>
然后在分配 DataContext(构造函数或 DataContextChanged 事件)之后,我这样做了:
(this.Resources["VM"] as ObjectDataProvider).ObjectInstance = this.DataContext;
在 Combobox xaml 中,我将其用作绑定源:
ItemsSource="{Binding Source={StaticResource VM}, Path=SomeItems, Mode=OneWay}"
不确定它是否适用于 microsoft datagrid,但我想值得一试。
这就是我将 ViewModel 与 ComboBoxes 一起使用的方式,DataContext 是 ViewModel,而不是底层实体 (List<Person>)。
ViewModel(Person 是一个具有 Name 和 Age 的 Simple 类):
public class PeopleViewModel : INotifyPropertyChanged
{
private List<Person> _peopleList;
private Person _selectedPerson;
public PeopleViewModel()
{
// initialize with sample data
_peopleList = getPeopleList();
}
// gets sample data
private List<Person> getPeopleList()
{
var result = new List<Person>();
for (int i = 0; i < 10; i++)
{
result.Add(new Person("person " + i, i));
}
return result;
}
public List<Person> PeopleList
{
get { return _peopleList; }
}
public Person SelectedPerson
{
get { return _selectedPerson; }
set
{
if (_selectedPerson == value) return;
_selectedPerson = value;
// required so that View know about changes
OnPropertyChanged("SelectedPerson");
}
}
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
// WPF will listen on this event for changes
public event PropertyChangedEventHandler PropertyChanged;
}
组合框的 XAML:
<ComboBox Name="cmbEnum" Width="150" ItemsSource="{Binding Path=PeopleList}" SelectedValue="{Binding Path=SelectedPerson}" SelectedValuePath="" DisplayMemberPath="Name" ></ComboBox>
在后面的代码中我可以做到:
public Window2()
{
InitializeComponent();
vm = new PeopleViewModel();
// we are listening on changes of ViewModel, not ComboBox
vm.PropertyChanged += new PropertyChangedEventHandler(vm_PropertyChanged);
this.DataContext = vm;
}
void vm_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "SelectedPerson")
{
MessageBox.Show(vm.SelectedPerson.Age.ToString());
}
}
// button1_Click should be probably replaced by Command
private void button1_Click(object sender, RoutedEventArgs e)
{
// sample showing that GUI is updated when ViewModel changes
vm.SelectedPerson = vm.PeopleList[2];
}
希望这会有所帮助,我对 WPF 很陌生,如果这是使用 MVVM 的正确方法,我想听听任何反馈,我认为它非常优雅,因为您只处理代码中的 ViewModel 和 Model,以及 View可以更换。
我发现实现这一点的最佳方法是为我在网格中使用的所有查找定义一些外部类,并将它们作为静态资源嵌入到模板中
我们最终为每个组合框列表提供了具有静态属性的类:
(你不能使类本身静态,否则 XAML 将无法打开它,但你不会得到编译错误)
例如:
public class ZoneList
{
private static readonly IList<Zone> _Items = new List<Zone>();
public static IList<Zone> Items
{
get { return _Items; }
}
}
然后在 XAML 中:
<UserControl.Resources>
<ResourceDictionary>
<ObjectDataProvider x:Key="myZoneList" ObjectType="{x:Type StaticLists:ZoneList}"/>
</ResourceDictionary>
</UserControl.Resources>
<ComboBox ItemsSource="{Binding Path=Items, Source={StaticResource myZoneList}}"></ComboBox>