2016-07-28 50 views
0

我有一個ComboBox綁定到一個簡單的ViewModel人的名單。 SelectedPerson被設置在ViewModel的構造函數中,但是當我運行應用程序時,ComboBox沒有設置其初始值。我究竟做錯了什麼?組合框不自動選擇初始值

請注意,MyPerson類的兩個實例具有相同的ID時應視爲相等。

重要提示:我無法修改MyPerson以覆蓋Equals(它是第三方)。

我目前看到的唯一選擇是使用適配器模式來包裝此類的實例並在其中實現自定義Equals方法。

我覺得應該有一個更好的WPF原生方法,通過某種「關鍵」從列表中匹配項目。就我而言,項目列表和所選項目來自不同的來源,這就是爲什麼他們有一個Id屬性充當主鍵。

請看看代碼,我玩過SelectedValue和SelectedValuePath,但沒有任何效果。

<Window x:Class="Test.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:vm="clr-namespace:Test" 
     mc:Ignorable="d" 
     x:Name="Root" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <vm:MainViewModel /> 
    </Window.DataContext> 
    <ComboBox ItemsSource="{Binding People}" SelectedItem="{Binding SelectedPerson}" SelectedValuePath="Id" 
       DisplayMemberPath="Name" 
       SelectedValue="{Binding SelectedPerson}" /> 
</Window> 

而這個視圖模型爲的DataContext:

public class MainViewModel 
{ 
    public MainViewModel() 
    { 
     SelectedPerson = new MyPerson { Name = "Mary", Id = 1 }; 
    } 

    public MyPerson SelectedPerson { get; set; } 

    public IEnumerable<MyPerson> People { get; } = new List<MyPerson>() 
    { 
     new MyPerson() {Name = "Mary", Id = 1 }, 
     new MyPerson() {Name = "John", Id = 2 }, 
    }; 
} 

public class MyPerson 
{ 
    public string Name { get; set; } 
    public int Id { get; set; } 
} 
+1

1)首先爲您的MainViewModel使用'INotifyPropertyChanged'接口。 2)添加'OnPropertyChange'(或者你會調用它)到'selectedPerson'設置器 – Shakra

+0

1)首先爲你的MainViewModel使用'INotifyPropertyChanged'接口。 2)添加'OnPropertyChange'(或者你會調用它)到'selectedPerson'設置器 3)你以錯誤的方式使用'SelectedValue' - > [Article](http://www.codeproject.com/Articles/ 671544/Understanding-SelectedValue-SelectedValuePath-Sele) 4)更好地使用SelectedItemIndex來檢查選擇的項目。 Atm你提供名爲Mary和Id = 1的不同對象的'SelectedPerson'和'People'列表,這可能會帶來一些問題。 *由於5分鐘的限制,無法編輯))* – Shakra

+0

@Shakra在這種情況下,我不需要實現接口。在第一次加載組合時,應該查詢該值而不更改通知。 – SuperJMN

回答

0

變化

public MainViewModel() 
{ 
    SelectedPerson = new MyPerson { Name = "Mary", Id = 1 }; 
} 

public MainViewModel() 
{ 
    SelectedPerson = People.ElementAt(0); 
} 

或者,如果歐要按名稱:

public MainViewModel() 
{ 
    SelectedPerson = People.First(x=> x.Name=="Mary"); 
} 
1

的問題是,新的對象創建這裏

SelectedPerson = new MyPerson { Name = "Mary", Id = 1 }; 

心不是」一樣在你的列表中,這樣的Equals方法將返回在所有情況下False

正如別人已經建議,你必須得到真正的對象,它是在列表中這樣做:

public MainViewModel(){ 
    SelectedPerson = People.First(x=> x.Name.Equals("Mary")); //Or: x.Id == 1 
} 

但也有另一種解決方案:您可以覆蓋Equals功能在你的MyPerson類,因此每個MyPerson實例與Name和/或Id確實會被視爲同一個人。

編輯

當你使用你的項目的ViewModels,如果你有一個視圖模型爲MyPerson類也可能會更好。它會解決你的問題使你的設計更好!

+0

對不起,我忘了說MyClass是我無法修改的第三方類。我修改了這個問題。 – SuperJMN

+1

您仍然可以使用第一個解決方案來獲得所需的結果。如果屬性值是,WPF不知道對象是相同的。如果你使用MVVM會更容易。你的ViewModel會(就像你在回答中所說的那樣)成爲你真實對象的一種包裝。 –

+1

如果你的MyPerson對象有一個ViewModel會更好! –