C# 如何从由对象填充的组合框中选择对象的实例
这个问题可能很愚蠢,但我是WPF的新手,所以我很抱歉。 我在这里发现了很多类似的问题,但都没有帮助 我有一个表单,它获取一些带有C# 如何从由对象填充的组合框中选择对象的实例,c#,.net,wpf,xaml,data-binding,C#,.net,Wpf,Xaml,Data Binding,这个问题可能很愚蠢,但我是WPF的新手,所以我很抱歉。 我在这里发现了很多类似的问题,但都没有帮助 我有一个表单,它获取一些带有位置属性的对象作为输入。 我希望在显示表单时在组合框中选择此位置属性。 我还希望使此属性在表单的生命周期中可以更改 我是这样做的: <ComboBox Name="CB_Location" ItemsSource="{Binding Locations}" SelectedItem="{Binding Select
位置
属性的对象作为输入。
我希望在显示表单时在组合框中选择此位置
属性。
我还希望使此属性在表单的生命周期中可以更改
我是这样做的:
<ComboBox Name="CB_Location" ItemsSource="{Binding Locations}" SelectedItem="{Binding SelectedLocation}" DisplayMemberPath="LocationName" SelectedValuePath="LocationID" SelectionChanged="CB_Location_SelectionChanged"/>
公共表单(object\u obj)
{
初始化组件();
lctrl=新位置控制器();
Locations=lctrl.GetAllLocations();
SelectedLocation=lctrl.GetLocationById(_obj.LocationID);
DataContext=this;
}
公共列表位置{get;set;}
公共场所选择场所;{get;set;}
组合框
正确填充了对象,但我无法正确设置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"/>
然后,您可以使用值路径LocationID
(不带SelectedItem
)将其绑定到SelectedValue
)
为什么在不使用SelectedValue的情况下设置SelectedValuePath?什么是SelectedLocation?如果它是当前DataContext中Location类型的属性,请确保其值是Location集合成员的Location对象。否则,将其转换为
int
类型的属性,绑定SelectedValue而不是SelectedItem,并将其设置为SelectedLocation=\u obj.LocationID代码>是,SelectedLocation是位置类型的属性。位置集合包含所有可能的位置,包括SelectedLocation。公共位置SelectedLocation代码>是一个字段,而不是属性。@Clemens修复了这个问题。非常感谢。但还是不行。谢谢那个家伙。我已经将SelectedLocation设置为公共财产。但是SelectedLocation仍然没有正确地应用于combobox。这很奇怪,但SelectedLocationID似乎起了作用。现在ComboBox显示值,SelectionChanged正在工作。我现在很感兴趣,哪种方法更正确:保持原样,还是继续尝试ObservableCollection之类的东西。@PavelPolushin这不应该与ObservableCollection
相关。只有在运行时修改集合时才需要它。如果您在构造函数中创建了一个集合,但从未对其进行过修改,则不需要它,一个简单的列表就足够了(或只读集合)。考虑到GetLocationById
返回与mm8在另一个答案中显示的Locations
中存在的项的相同实例,这两种方法应该都可以正常工作。两者都是正确的,这取决于您的用例哪个更适合。重要的是不要在XAML中混合使用这两种方法(意外结果)。
public Location SelectedLocation { get; set; }
<ComboBox Name="CB_Location"
ItemsSource="{Binding Locations}"
SelectedItem="{Binding SelectedLocation}"
DisplayMemberPath="LocationName"
SelectionChanged="CB_Location_SelectionChanged"/>
public int SelectedLocationID { get; set; }
<ComboBox Name="CB_Location"
ItemsSource="{Binding Locations}"
DisplayMemberPath="LocationName"
SelectedValuePath="LocationID"
SelectedValue="{Binding SelectedLocationID}"
SelectionChanged="CB_Location_SelectionChanged"/>
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.
}