2016-07-28 44 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会更好! –