未显示组合框中选定的属性
本文关键字:属性 显示 组合 | 更新日期: 2023-09-27 17:53:59
我有一个ViewModel,它有一个集合和一个表示集合中所选值的属性。在我看来,这是显示在一个组合框。当"填充"我的ViewModel时,选中的项目不会显示在我的视图中。
我ViewModelpublic class DriverViewModel : MasterDataWithAddressViewModel<Driver>
{
public ObservableCollection<Vehicle> Vehicles
{
get { return _vehicles; }
set
{
if (_vehicles != value)
{
_vehicles = value;
RaisePropertyChanged("Vehicles");
}
}
}
public Vehicle SelectedVehicle
{
get { return PrimaryModel.Vehicle; }
set
{
if (PrimaryModel.Vehicle != value)
{
PrimaryModel.Vehicle = value;
RaisePropertyChanged("SelectedVehicle");
}
}
}
}
SelectedVehicle
的setter被正确调用,RaisePropertyChanged("SelectedVehicle");
也被正确调用…
<ComboBox DisplayMemberPath="Number"
ItemsSource="{Binding Vehicles, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedVehicle, UpdateSourceTrigger=PropertyChanged}" />
我也试过这样做:
<ComboBox DisplayMemberPath="Number"
ItemsSource="{Binding Vehicles, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding SelectedVehicle, UpdateSourceTrigger=PropertyChanged}"
IsSynchronizedWithCurrentItem="True" />
在组合框中"手动"选择一个值(通过视图)没有问题。在代码中"填充"ViewModel是行不通的。
有谁能帮忙吗?
因为你的属性SelectedVehicle
是引用类型
当你将SelectedValue
绑定到ViewModel.SelectedVehicle
时
combobox比较有界集合的对象和SelectedVehicle
的对象
通过调用.Equals
方法进行比较,该方法默认比较引用,如果两个对象引用相同的内存地址,则返回true
因为所选项目没有显示,我假设SelectedVehicle
的引用不在集合Vehicles
中。
您可以在Vehicle
类中重写Equals
方法以通过某些属性进行比较。对你来说,这是最快捷的方法。
在SelectedItem
中使用第二种方法,并在Vehicle
类中重写Equals
方法:
public override bool Equals(Person compareTo)
{
if (compareTo == null)
return false;
return (this.ID == compareTo.ID);
}
或者我更喜欢next方法more
使用识别ValueMemberPath
车辆的属性
<ComboBox DisplayMemberPath="Number"
ValueMemberPath="Number"
ItemsSource="{Binding Vehicles, UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedVehicle, UpdateSourceTrigger=PropertyChanged}" />
In ViewModel
public Int32 SelectedVehicleNumber
{
get { return PrimaryModel.Vehicle.Number; }
set
{
if (PrimaryModel.Vehicle.Number != value)
{
PrimaryModel.Vehicle = New Vehicle(value);//Create instance by selected value
RaisePropertyChanged("SelectedVehicle");
}
}
}
还有一种方法是KeyedCollection
尝试绑定SelectedItem
而不是SelectedValue
。
Vehicles
属性设置在 SelectedVehicle
属性之前
我做了一个小例子:
我有这个简单的视图:
<Window x:Class="ComboSelectedItemBinding.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ComboSelectedItemBinding"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.DataContext>
<local:ViewModel/>
</Grid.DataContext>
<StackPanel>
<ComboBox ItemsSource="{Binding vehicles, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding VehicleSelected}" DisplayMemberPath="Name" SelectedIndex="0" VerticalAlignment="Top"/>
<TextBox x:Name="VehName" MinWidth="120" Margin="80,10" />
<Button Content="Change selection" Command="{Binding ChangeCommand}" CommandParameter="{Binding ElementName=VehName, Path=Text}" Margin="10" Width="150"/>
</StackPanel>
</Grid>
这是模型:
public class Vehicle : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
public event PropertyChangedEventHandler PropertyChanged = delegate { };
public void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName ));
}
}
ViewModel:
public class ViewModel : DependencyObject
{
public ObservableCollection<Vehicle> vehicles { get; set; }
public ICommand ChangeCommand { get; set; }
public Vehicle VehicleSelected
{
get { return (Vehicle)GetValue(VehicleSelectedProperty); }
set { SetValue(VehicleSelectedProperty, value); }
}
// Using a DependencyProperty as the backing store for VehicleSelected. This enables animation, styling, binding, etc...
public static readonly DependencyProperty VehicleSelectedProperty =
DependencyProperty.Register("VehicleSelected", typeof(Vehicle), typeof(ViewModel), new PropertyMetadata(null));
public ViewModel()
{
vehicles = new ObservableCollection<Vehicle>();
Vehicle veh1 = new Vehicle() { Name = "V1" };
Vehicle veh2 = new Vehicle() { Name = "V2" };
Vehicle veh3 = new Vehicle() { Name = "V3" };
Vehicle veh4 = new Vehicle() { Name = "V4" };
vehicles.Add(veh1);
vehicles.Add(veh2);
vehicles.Add(veh3);
vehicles.Add(veh4);
ChangeCommand = new ChangeCommand(this);
}
}
和按钮命令:
public class ChangeCommand : ICommand
{
public ViewModel _vm = null;
public ChangeCommand(ViewModel vm)
{
_vm = vm;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_vm.VehicleSelected = _vm.vehicles.First( name => name.Name.Equals(parameter.ToString()));
}
}
为了在该组合框中进行更改,您必须在其有界集合中保持对其中一个对象的引用。为了实现这一点,我添加了根据车辆名称更改选择的方法。对于车辆名称,您可以在列表中搜索所引用的项目,并将其设置为SelectedItem, SelectedItem被定义为DependencyProperty,只是为了做一个小小的改变。