繁体   English   中英

从对象设置ComboBox的SelectedItem

[英]Set SelectedItem of ComboBox from object

我正在使用提供数据的Entity Framework 6(EF)在Visual Studio 2015中构建MVVM Light WPF应用程序。 我有一个ComboBox ,显示了有人需要进行药物测试的原因,它看起来像这样:

<ComboBox ItemsSource="{Binding ReasonsForTest}"
    SelectedItem="{Binding Path=ReasonsForTestVm,
                     UpdateSourceTrigger=PropertyChanged}"
    DisplayMemberPath="Description" />

ReasonsForTest的类型为ReasonForTestViewModel类:

public class ReasonForTestViewModel: ViewModelBase
{
    private int _ReasonForTestId;
    private string _ReasonForTestAbbr;
    private string _description;

    public int ReasonForTestId
    {
        get { return _ReasonForTestId; }
        set
        {
            if (value == _ReasonForTestId) return;
            _ReasonForTestId = value;
            RaisePropertyChanged();
        }
    }

    public string ReasonForTestAbbr
    {
        get { return _ReasonForTestAbbr; }
        set
        {
            if (value == _ReasonForTestAbbr) return;
            _ReasonForTestAbbr = value;
            RaisePropertyChanged();
        }
    }

    public string Description
    {
        get { return _description; }
        set
        {
            if (value == _description) return;
            _description = value;
            RaisePropertyChanged();
        }
    }
}

我有一个数据服务类,其中包含以下代码来获取ComboBox的有效值的数据:

public async Task<ObservableCollection<ReasonForTestViewModel>> GetReasonsForTest()
{
    using (var context = new MyEntities())
    {
        var query = new ObservableCollection<ReasonForTestViewModel>
            (from rt in context.ReasonForTests
             orderby rt.description
             select new ReasonForTestViewModel
             {
                 ReasonForTestId = rt.ReasonForTestID,
                 ReasonForTestAbbr = rt.ReasonForTestAbbr,
                 Description = rt.description,
             });
        return await Task.Run(() => query);
    }
}

视图模型使用以下方法填充ComboBox

var dataService = new TestDataService();    
ReasonsForTest = await dataService.GetReasonsForTest();

ComboBox具有正确的数据; 但是,当应用程序启动时,它没有选择正确的值 - 它在加载时显示为空白。 SelectedItemReasonsForTestVm )也属于类类型ReasonForTestViewModel并从数据库中填充此人员的一个项目。 我已经逐步完成了代码以确保ReasonsForTestVm具有正确的数据,而且确实如此。

这是ReasonsForTestVm的属性:

public ReasonForTestViewModel ReasonForTestVm
{
    get
    {
        return _reasonForTestVm;
    }

    set
    {
        if (Equals(value, _reasonForTestVm)) return;
        _reasonForTestVm = value;
        RaisePropertyChanged();
    }
}

我在这做错了什么? 我快要疯了!

更新 :对不起上面的财产令人困惑的名字。 固定。

任何WPF项控件扩展Selector (例如ComboBox和ListBox)都有两个经常结合使用的属性: ItemsSourceSelectedItem

将集合绑定到ItemsSource ,UI中会显示这些项的表示形式。 每个表示都绑定到在ItemsSource绑定的集合中找到的实例。 例如,如果您正在使用DataTemplate来创建该表示,那么您将在每个内容中找到DataContext将是该集合中的其中一个实例。

当您选择其中一个表示时, SelectedItem属性现在保存绑定到该表示的集合中的实例。

这通过用户与UI的交互完美地工作。 但是,在以编程方式与这些控件交互时,有一个重要的警告。

将这些属性绑定到视图模型中的类似属性是一种非常常见的模式。

public class MuhViewModel
{
    public MuhItems[] MuhItems {get;} = new[]{ new Item(1), new Item(2) };

    // I don't want to show INPC impls in my sample code, kthx
    [SuperSlickImplementINotifyPropertyChangedAttribute]
    public MuhSelectedItem {get;set;}
}

势必

<ComboBox ItemsSource="{Binding MuhItems}"
          SelectedItem="{Binding MuhSelectedItem}" />

如果您尝试以这种方式手动更新所选项目...

muhViewModel.MuhSelectedItem = new Item(2);

用户界面不会改变。 Selector看到ItemsSource已更改,是的,但它没有在ItemsSource集合中找到该实例。 它不知道具有值2的Item的一个实例等同于具有相同值的任何其他Item。 所以它什么都不做。 (对于真正发生的事情来说,这有点过于简单。你可以破坏JustDecompile并亲眼看看。它在那里真正令人费解。)

在这种情况下,您应该做的是使用绑定到ItemsSource的集合中找到的实例更新SelectedItem 在我们的例子中,

var derp = muhViewModel.MuhItems.FirstOrDefault(x => x.MuhValue == 2);
muhViewModel.MuhSelectedItem = derp;

旁注,在调试会话中跟踪实例时,有助于使用Visual Studio的Make Object ID功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM