在WPF中显示选定的ComboBox项

时间:2015-07-14 22:53:08

标签: c# wpf mvvm

我正在尝试构建一个显示所选项目的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");
            }
        }
    }
    ...
}

我有ObservableCollectionAnimalViewModel个对象:

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。它 正确设置项目。

任何帮助都将不胜感激。

2 个答案:

答案 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"/>

屏幕加载结果:

enter image description here

答案 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,您就可以了。