我正在尝试构建一个显示所选项目的ComboBox。我可以让组合框轻松地显示选项,但是显示所选项目是不起作用的。所选项目是指从数据库中提取的值。
我知道set方法正常,因为我可以成功存储用户的选择。但是,当我从数据库中抓取它时,我似乎无法让ComboBox填充所选项目。
我已经对此感到沮丧几周了,我觉得这个错误很简单。
方案:
我有Animal Model
public class AnimalModel
{
public string AnimalName { get; set; }
...
}
每个AnimalViewModel
我都有一个Animal
:
public class AnimalViewModel: BindableBase
{
private AnimalViewModel _animal;
public AnimalViewModel(AnimalModel animal)
{
_animal = animal;
}
public string AnimalName
{
get { return _animal.Name; }
set
{
if (value != this._animal.Name)
{
this._animal.Name = value;
OnPropertyChanged("AnimalName");
}
}
}
...
}
我有ObservableCollection
个AnimalViewModel
个对象:
public class TemplateViewModel : BindableBase
{
private ObservableCollection<AnimalViewModel> _animals;
public TemplateViewModel(...)
{
_animal = methodReturnsAnObservableCollectionOfAnimalViewModels();
}
public ObservableCollection<AnimalViewModel> Animals
{
get { return _animals; }
set
{
if (value != this._animals)
{
this._animals = value;
OnPropertyChanged("Animals");
}
}
}
}
有了这个,我可以在ComboBox中轻松显示AnimalName
的列表:
<ComboBox ItemsSource="{Binding Animals}"
DisplayMemberPath="AnimalName"
IsEditable="True"
IsReadOnly="True"
Text="--- Select Animal ---"/>
我现在绑定到SelectedItem
public class TemplateViewModel
{
...
private AnimalViewModel _selectedAnimal;
public TemplateViewModel(MyObject, ...)
{
...
_selectedAnimal = new AnimalViewModel(new AnimalModel() { AnimalName = MyObject.AnimalName });
}
...
public AnimalViewModel SelectedAnimal
{
get { return _selectedAnimal; }
set
{
if (value != _selectedAnimal)
{
_selectedAnimal = value;
AnimalName = value.AnimalName;
OnPropertyChanged("SelectedAnimal");
}
}
}
}
现在,我有:
<ComboBox ItemsSource="{Binding Animals}"
DisplayMemberPath="AnimalName"
SelectedItem={Binding SelectedAnimal}
SelectedValuePath="AnimalName"
IsEditable="True" IsReadOnly="True"
Text="--- Select Animal ---"/>
不幸的是,这并没有使用Animal填充ComboBox。它只是在填充选项的情况下提取默认选项Select Animal
。它 正确设置项目。
任何帮助都将不胜感激。
答案 0 :(得分:3)
您需要访问相关动物的实际reference
。
在代码隐藏中,您创建一个动物,它看起来像ObservableCollection中的动物,但它不是引用的动物。
更改(加载动物后)
_selectedAnimal = new AnimalViewModel(...);
to(仅使用Property访问者,而不是后备存储变量;因此更改事件触发,顺便说一句)
SelectedAnimal = Animals[0];
测试应用(格式如网格行/列已删除)
<Label>SelectedItem</Label>
<TextBlock Text="{Binding SelectedItem, ElementName=cbMain}"/>
<Label >SelectedValue</Label>
<TextBlock Text="{Binding SelectedValue, ElementName=cbMain}"/>
<Button Click="ChangeSelectedValue">Set Selected Value</Button>
<ComboBox Name="cbMain"
ItemsSource="{Binding Ships}"
SelectedItem="{Binding Ships[0]}"
SelectedValuePath="Name"
Text="Select a Ship"/>
屏幕加载结果:
答案 1 :(得分:2)
我认为这是SelectedValuePath="AnimalName"
与您的财产之间的命名差异。
public string Animal //<----Should Be AnimalName!
{
get { return _animal.Name; }
set
{
if (value != this._animal.Name)
{
this._animal.Name = value;
OnPropertyChanged("AnimalName");
}
}
}
将您的财产更改为AnimalName,您就可以了。