2012-07-14 19 views
9

Tengo un problema extraño en mi aplicación WinRT/C# XAML Metro, utilizando Windows 8 Release Preview (últimos parches instalados). Estoy usando un ComboBox, cuyos valores ItemsSource y SelectedValue están ligados a las propiedades en un modelo de vista:ComboBox SelectedValue no muestra

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

Código atrás:

public MainPage() 
{ 
    this.InitializeComponent(); 

    DataContext = new TestViewModel(); 
} 

y una definición muy simple de la TestViewModel, el uso de cadenas:

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")); 
      } 
     } 
    } 
} 

Ahora pensé que esta solución simple debería funcionar ... Pero cuando inicio la aplicación, el SelectedValue="Test Item 2" no aparece, el ComboBox se deja vacío. Al establecer puntos de interrupción noté que los valores límite MyItemsSource y MySelectedValue se recuperan corectly del Modelo de Vista cuando configuro el DataContext de la vista. Después de esta acción, la propiedad ComboBox.SelectedValue está realmente configurada en "Test Item 2", ¡pero simplemente no se muestra! También noté que cuando cambio el valor seleccionado en el ComboBox por acción del usuario en la interfaz de usuario, el valor cambiado aparece en el ComboBox y la propiedad Ver modelo se actualiza en consecuencia. Así que todo parece funcionar bien, excepto la visualización inicial de la propiedad del modelo de vista MySelectedValue. Me estoy volviendo realmente desesperado sobre eso ...

Ahora bien, aunque este es el ejemplo más simple, en el origen quise vincular entidades enteras a ComboBox, estableciendo DisplayMemberPath y SelectedValuePath. Desafortunadamente, ocurre el mismo problema.

+0

¿Eso es trabajo para usted? –

+0

¿El problema persiste si obtiene un elemento real de la colección, en lugar de asignar "una nueva cadena" a selectedValue, como en 'selectedValue = itemsSource [1]'? – Patrick

Respuesta

29

He encontrado el problema en mi ejemplo: En el marcado XAML he definido la propiedad SelectedValueantes de la propiedad ItemsSource. Si cambio ambas definiciones de esta manera, funciona:

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

Esto es realmente extraño y molesto. Ahora me gustaría saber: ¿esto es un error o diseño? Creo que esto es un error, porque el control debería funcionar independientemente del orden de las propiedades definidas en XAML.

+0

esto fue desde Silverlight 2. –

+0

Gracias por la sugerencia. He estado usando Silverlight/WPF/Windows8 durante años y nunca he notado el orden de las cuestiones vinculantes. Recientemente me encontré con este problema al desarrollar una aplicación de Windows8, me tomó un tiempo darme cuenta de que 'SelectedValue' era anterior a la unión de' ItemsSource'. –

+0

realmente? No creía que esto importara –

2

esta solución funciona: Usted puede encontrar aquí 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> 

clase ViewModle es

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]" }); 
     } 
    } 
Cuestiones relacionadas