2012-07-14 131 views
9

使用Windows 8 Release Preview(已安装最新的修补程序),我的WinRT/C#XAML Metro应用程序出现了一个奇怪的问题。我使用的是ComboBox,其值ItemsSourceSelectedValue必然属性在视图模型:ComboBox SelectedValue不显示

<ComboBox SelectedValue="{Binding MySelectedValue, Mode=TwoWay}" 
      ItemsSource="{Binding MyItemsSource, Mode=OneWay}" 
      Width="200" Height="30" /> 

后面的代码:

public MainPage() 
{ 
    this.InitializeComponent(); 

    DataContext = new TestViewModel(); 
} 

而且TestViewModel的一个非常简单的定义,使用字符串:

public class TestViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    private IEnumerable<string> _myItemsSource = new List<string> 
     { 
      "Test Item 1", 
      "Test Item 2", 
      "Test Item 3" 
     }; 
    public IEnumerable<string> MyItemsSource 
    { 
     get { return _myItemsSource; } 
    } 

    private string _mySelectedValue = "Test Item 2"; 
    public string MySelectedValue 
    { 
     get { return _mySelectedValue; } 
     set 
     { 
      _mySelectedValue = value; 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs("MySelectedValue")); 
      } 
     } 
    } 
} 

现在我认为这个简单的解决方案应该只是工作......但是当我启动应用程序时,SelectedValue="Test Item 2"不显示,ComboBox留空。通过设置断点,我注意到当我设置视图的DataContext时,从视图模型中正确检索了绑定值MyItemsSourceMySelectedValue。在此操作之后,ComboBox.SelectedValue属性实际上设置为"Test Item 2",但它只是不显示!另外我注意到,当我通过用户界面上的用户操作更改组合框中的选定值时,更改后的值显示在组合框中,并且视图模型属性也会相应更新。因此除了最初的可视化模型属性MySelectedValue以外,一切看起来都很好。我正变得非常绝望...

现在,虽然这是最简单的例子,但在起源中,我想将整个实体绑定到ComboBox,设置DisplayMemberPathSelectedValuePath。不幸的是,同样的问题发生。

+0

是你的工作? – 2012-07-14 09:48:33

+0

如果您从集合中获取实际元素,而不是像'selectedValue = itemsSource [1]'中那样将“新字符串”分配给selectedValue,问题是否会持续存在? – Patrick 2012-07-14 09:50:41

回答

29

我发现在我的例子问题:在XAML标记,我已经定义了SelectedValue财产之前ItemsSource属性。如果我以这种方式交换两个定义,它将起作用:

<ComboBox ItemsSource="{Binding MyItemsSource, Mode=OneWay}" 
     SelectedValue="{Binding MySelectedValue, Mode=TwoWay}" 
     Width="200" Height="30" /> 

这真的很奇怪,很讨厌。现在我想知道:这是一个错误还是设计?我认为这是一个错误,因为无论XAML中定义的属性的顺序如何,控件都应该工作。

+0

这是自Silverlight 2以来。 – 2012-12-05 23:41:48

+0

感谢您的提示。我一直在使用Silverlight/WPF/Windows8多年,从未注意到绑定事项的顺序。最近我在开发Windows8应用程序时遇到了这个问题,我花了一段时间才意识到'SelectedValue'在'ItemsSource'绑定之前。 – 2013-01-14 20:31:00

+0

真的吗?我不认为这很重要 – 2013-02-05 17:02:32

2

这是工作的解决方案:你可以在这里找到https://skydrive.live.com/?cid=b55690d11b67401d&resid=B55690D11B67401D!209&id=B55690D11B67401D!209

<ComboBox Width="300" Height="32" HorizontalAlignment="Left" DisplayMemberPath="Name" 
        VerticalAlignment="Top" ItemsSource="{Binding PersonCollection}" 
        SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"></ComboBox> 

ViewModle类是

public class ViewModel:BaseViewModel 
    { 
     private Person selectedPerson; 
     public Person SelectedPerson { 
      get { return this.selectedPerson; } 
      set { this.selectedPerson = value; 
      this.RaisePropertyChanged("SelectedPerson"); 
      } 
     } 
     public ObservableCollection<Person> PersonCollection { get; set; } 

     public ViewModel() 
     { 
      this.PersonCollection = new ObservableCollection<Person>(); 
      this.PopulateCollection(); 

      //setting first item as default one 
      this.SelectedPerson = this.PersonCollection.FirstOrDefault(); 
     } 

     private void PopulateCollection() 
     { 
      this.PersonCollection.Add(new Person { Name="Oscar", Email="[email protected]" }); 
      this.PersonCollection.Add(new Person { Name = "Jay", Email = "[email protected]" }); 
      this.PersonCollection.Add(new Person { Name = "Viral", Email = "[email protected]" }); 
     } 
    }