这个问题可能很愚蠢,但我是WPF的新手,所以我很抱歉。我在这里发现了很多类似的问题,但是没有一个对我有帮助。
我有一个表单,得到一些对象与Location
属性作为输入。我想要这个Location
属性被选择在ComboBox
时,形式显示。我还想让这个属性在表单的生命周期中是可变的。
我是这样做的:
<ComboBox Name="CB_Location" ItemsSource="{Binding Locations}" SelectedItem="{Binding SelectedLocation}" DisplayMemberPath="LocationName" SelectedValuePath="LocationID" SelectionChanged="CB_Location_SelectionChanged"/>
public class Location
{
public int LocationID { get; set; }
public string LocationName { get; set; }
}
public Form(object _obj)
{
InitializeComponent();
lctrl = new LocationController();
Locations = lctrl.GetAllLocations();
SelectedLocation = lctrl.GetLocationById(_obj.LocationID);
DataContext = this;
}
public List<Location> Locations { get; set; }
public Location SelectedLocation; { get; set; }
ComboBox
正确地填充了对象,但是我不能正确地设置SelectedItem
属性。
所选项目未设置的问题是因为SelectedLocation
是一个字段,您无法绑定它。有关绑定源的更多信息,可以参考文档。
您可以绑定到任何公共语言运行时(CLR)对象的公共属性、子属性以及索引器。绑定引擎使用CLR反射来获取属性的值。或者,实现ICustomTypeDescriptor或具有注册的TypeDescriptionProvider的对象也可以使用绑定引擎。
为了使当前的代码正常工作,只需将SelectedLocation
设置为公共属性。
public Location SelectedLocation { get; set; }
除此之外,如果你只想绑定选中的项目,设置SelectedValuePath
是没有用的。
<ComboBox Name="CB_Location"
ItemsSource="{Binding Locations}"
SelectedItem="{Binding SelectedLocation}"
DisplayMemberPath="LocationName"
SelectionChanged="CB_Location_SelectionChanged"/>
如果您想将SelectedValue
绑定到适用SelectedValuePath
的地方,则必须公开一个与所选值路径类型匹配的属性,这里是int
。
public int SelectedLocationID { get; set; }
然后你可以将SelectedValue
与值路径LocationID
绑定(没有SelectedItem
)。
<ComboBox Name="CB_Location"
ItemsSource="{Binding Locations}"
DisplayMemberPath="LocationName"
SelectedValuePath="LocationID"
SelectedValue="{Binding SelectedLocationID}"
SelectionChanged="CB_Location_SelectionChanged"/>
关于更新属性的另一个注意事项。看来你没有实现INotifyPropertyChanged
接口。例如,如果您设置了Location
,用户界面(这里是ComboBox
)将不会反映更改,因为它不会得到通知。因此,如果你想改变Location
或其他属性绑定在你的表单,你必须实现INotifyPropertyChanged
,例如:
public class YourViewModel : INotifyPropertyChanged
{
private Location _selectedLocation;
public Location SelectedLocation
{
get => _selectedLocation;
set
{
if (_selectedLocation == value)
return;
_selectedLocation = value;
OnPropertyChanged();
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
// ...other code.
}