簡體   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