2011-05-26 33 views
8

Tengo un combobox que se une a una colección de Foo en mi viewmodel (FooCollection). Asimismo, establecer la propiedad SelectedItem del cuadro combinado a una propiedad en mi modelo de vista del tipo de llamada FooSelectedFooCombobox SelectedItem no funciona como se esperaba

entonces me puse FooCollection y SelectedFoo y fuego los eventos OnPropertyChanged apropiadas.

Mi cuadro combinado contiene la lista de Foo, pero el elemento que se muestra en el cuadro combinado siempre es el primer elemento de la lista. Sin embargo, si se despliega el cuadro combinado, el elemento que se resalta es el elemento correcto (SelectedFoo). Por lo tanto, está seleccionando el elemento correcto, pero no lo muestra.

<ComboBox Grid.Row="5" ItemsSource="{Binding Path=FooCollection}" 
         SelectedItem="{Binding SelectedFoo, Mode=TwoWay}" 
         Name="FooSelectionControl"/> 

¿Alguien sabe cómo solucionar este problema?

+0

¿Por casualidad para ver esta pregunta? ¿Ayuda? http://stackoverflow.com/questions/5896006/wpf-combobox-selecteditem-binding-doesnt-work – jwismar

+0

Gracias, pero eso es diferente, mi clase implementa INotifyPropertyChanged (que era la parte OnPropertyChanged de mi publicación) – Ben

+0

¿Has probado ' Modo de enlace OneWayToSource'? –

Respuesta

5

Hmm, funciona en mi extremo. ¿Qué tipo de colección estás usando?

Screenshot 1

Screenshot 2

<ComboBox 
     SelectedItem="{Binding SelectedFoo, Mode=TwoWay}" 
     ItemsSource="{Binding FooCollection}"> 
    </ComboBox> 

Código atrás:

public MainWindow() 
    { 
     InitializeComponent(); 

     DataContext = this; 

     FooCollection = new BindingList<Foo>(); 

     var foo = new Foo("Alpha"); 
     FooCollection.Add(foo); 

     foo = new Foo("Beta"); 
     SelectedFoo = foo; 
     FooCollection.Add(foo); 

     foo = new Foo("Gamma"); 
     FooCollection.Add(foo); 
    } 

    public Foo SelectedFoo 
    { 
     get { return (Foo)GetValue(SelectedFooProperty); } 
     set { SetValue(SelectedFooProperty, value); } 
    } 
    public static readonly DependencyProperty SelectedFooProperty = 
     DependencyProperty.Register("SelectedFoo", typeof(Foo), typeof(MainWindow), new UIPropertyMetadata(null)); 

    public BindingList<Foo> FooCollection 
    { 
     get { return (BindingList<Foo>)GetValue(FooCollectionProperty); } 
     set { SetValue(FooCollectionProperty, value); } 
    } 
    public static readonly DependencyProperty FooCollectionProperty = 
     DependencyProperty.Register("FooCollection", typeof(BindingList<Foo>), typeof(MainWindow), new UIPropertyMetadata(new BindingList<Foo>())); 

y la clase Foo,

public class Foo : INotifyPropertyChanged 
{ 
    public Foo(string name) 
    { 
     _name = name; 
    } 

    private string _name; 

    public string Name 
    { 
     get { return _name; } 
     set 
     { 
      if (_name == value) return; 

      _name = value; 
      OnPropertyChanged("Name"); 
     } 
    } 

    public override string ToString() 
    { 
     return Name; 
    } 

    #region INotifyPropertyChanged event 

    ///<summary> 
    ///Occurs when a property value changes. 
    ///</summary> 
    public event PropertyChangedEventHandler PropertyChanged; 


    /// <summary> 
    /// Raises the <see cref="PropertyChanged"/> event for 
    /// a given property. 
    /// </summary> 
    /// <param name="propertyName">The name of the changed property.</param> 
    protected void OnPropertyChanged(string propertyName) 
    { 
     //validate the property name in debug builds 
     VerifyProperty(propertyName); 

     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 


    /// <summary> 
    /// Verifies whether the current class provides a property with a given 
    /// name. This method is only invoked in debug builds, and results in 
    /// a runtime exception if the <see cref="OnPropertyChanged"/> method 
    /// is being invoked with an invalid property name. This may happen if 
    /// a property's name was changed but not the parameter of the property's 
    /// invocation of <see cref="OnPropertyChanged"/>. 
    /// </summary> 
    /// <param name="propertyName">The name of the changed property.</param> 
    [Conditional("DEBUG")] 
    private void VerifyProperty(string propertyName) 
    { 
     Type type = GetType(); 

     //look for a *public* property with the specified name 
     PropertyInfo pi = type.GetProperty(propertyName); 
     if (pi == null) 
     { 
      //there is no matching property - notify the developer 
      string msg = "OnPropertyChanged was invoked with invalid property name {0}: "; 
      msg += "{0} is not a public property of {1}."; 
      msg = String.Format(msg, propertyName, type.FullName); 
      Debug.Fail(msg); 
     } 
    } 

    #endregion 
} 
+0

Hola @tofutim, estaba usando una Lista <> pero la cambié a una ObservalbleCollection <> en función de que usabas una lista de encuadernación (no creo que esté disponible en Silverlight) y sé que funciona bien. Aclamaciones. – Ben

2

Quizás pruebe SelectedValue en lugar de SelectedItem. Además, asegúrese de que Foo.Equals() se implemente correctamente.

Cuestiones relacionadas