GitHub链接:https://github.com/babakin34/wpf_test/tree/master/WpfApp1
我有以下课程:
的ViewModels :
public class PersonVM : BindableBase
{
public int ID { get; set; }
private string _lastName;
public string LastName
{
get { return _lastName; }
set { SetProperty(ref _lastName, value); }
}
}
public class MainVM : BindableBase
{
public ObservableCollection<PersonVM> People { get; set; }
private PersonVM _selectedPerson;
public PersonVM SelectedPerson
{
get { return _selectedPerson; }
set { SetProperty(ref _selectedPerson, value); }
}
public MainVM()
{
People = new ObservableCollection<PersonVM>()
{
new PersonVM()
{
ID = 1,
LastName = "AA"
},
new PersonVM()
{
ID = 2,
LastName = "BB"
},
};
SelectedPerson = People.First();
}
}
查看:
<小时/>
<Grid>
<StackPanel>
<ComboBox ItemsSource="{Binding People}"
SelectedItem="{Binding SelectedPerson}"
DisplayMemberPath="LastName"
Margin="0,5,0,25"/>
<DataGrid ItemsSource="{Binding People}"/>
</StackPanel>
</Grid>
当用户选择由Datagrid的默认最后一个条目引起的空元素时,如何实现ComboBox中的“MainVM.SelectedPerson”?
PS:我正在使用棱镜,但问题不在于棱镜相关。您可以通过INotifyPropertyChanged替换BindableBase。答案 0 :(得分:2)
编辑: 这里真正的问题与我最初想的有点不同。选择插入行时,您会在输出窗口中看到WPF无法强制转换&#34; NamedObject&#34;进入&#34; PersonVM&#34;。 Datagrid为要使用的插入行创建NamedObject,但绑定根本不起作用,因为它的类型错误。 简洁的解决方案是创建一个转换器来检查对象是否为PersonVM类型,否则返回null(而不是NamedObject实例)。
public class MyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is PersonVM)
return value;
return null;
}
}
在xaml中
<DataGrid x:Name="DataGrid"
ItemsSource="{Binding People}"
SelectedCellsChanged="DataGrid_OnSelectedCellsChanged"
SelectedItem="{Binding SelectedPerson,
Converter={StaticResource myConverter}}"
又旧又脏
不是最好的方式,但是如果你不介意在代码隐藏中使用视图模型(或通过接口抽象),你可以使用&#34; SelectionChanged&#34;如果任何所选项目不是您需要的类型,则将ViewModel中的SelectedPerson设置为null。
private void Selector_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
bool invalidStuffSelected = false;
//throw new System.NotImplementedException();
foreach (var obj in DataGrid.SelectedItems)
{
if (!(obj is PersonVM))
invalidStuffSelected = true;
}
MainVM vm = (MainVM) this.DataContext;
if (invalidStuffSelected)
vm.SelectedPerson = null;
}
在你的例子中,selectionmode&#34; single&#34;因为组合框只能显示一个选定的值,所以会更有意义。