2010-11-09 23 views
14

Tengo el código subyacente a continuación:ObservableCollection obligatorio para WPF ListBox

public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     ObservableCollection<int> sampleData = new ObservableCollection<int>(); 
     public ObservableCollection<int> SampleData 
     { 
      get 
      { 
       if (sampleData.Count <= 0) 
       { 
        sampleData.Add(1); 
        sampleData.Add(2); 
        sampleData.Add(3); 
        sampleData.Add(4); 
       } 
       return sampleData; 
      } 
     } 
    } 

Mi xaml es:

<Window x:Class="Sandbox.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <ListBox ItemsSource="{Binding Path=SampleData}"/> 
    </Grid> 
</Window> 

La lista no muestra los valores de la colección (o nada en absoluto) ¿Puede alguien señalar cuál es mi error?

¿Debo configurar el DataContext explícitamente? Pensé que si no se configuraba ninguno, el control se usaría solo como el DataContext.

+0

¿Funciona si configura el DataContext explícitamente? – user200783

Respuesta

20

Sí, tendrá que configurar el DataContext de alguna manera. No tiene un DataContext porque la ventana no tiene un DataContext a menos que esté configurado. ListBox obtendrá el DataContext si hace esto en el constructor.

public MainWindow() 
{ 
    InitializeComponent(); 
    this.DataContext = this; 
} 

contrario, puede utilizar RelativeSource, etc. ElementName en la unión pero supongo que sabía que =)

4

por lo general pasan un modelo de vista en el constructor y establecer el DataContext al modelo de vista en el pasado. Entonces su ObservableCollection se puede mover de la vista y poner en el modelo de vista. Esto separa tu vista de tu lógica y también te permite probar el código del modelo de vista.

public MainWindow(SomeViewModel viewModel) 
{ 
    DataContext = viewModel; 

    InitializeComponent(); 
} 
2

intenta utilizar el patern MVVM por lo que en la vista se puede definir el cuadro de lista como esta:

<ListBox ItemsSource="{Binding Path=Log, UpdateSourceTrigger=PropertyChanged}"/> 

entonces la vista puede ser sin código detrás relacionado con el origen de enlace. En lo relacionado modelo de vista se agrega algo como esto:

public class ViewModel : ViewModelBase 
{ 
    //... 
    private ObservableCollection<string> p_Log; 

    /// <summary> 
    /// A log of a starting process 
    /// </summary> 
    public ObservableCollection<string> Log 
    { 
     get { return p_Log; } 

     set 
     { 
      base.RaisePropertyChangingEvent("Log"); 
      p_Log.Add(value.ToString()); 
      base.RaisePropertyChangedEvent("Log"); 
     } 
    } 
    //.... 
    /// <summary> 
    /// Initializes this view model. 
    /// </summary> 
    /// <param name="mainWindowViewModel">The view model for this application's main window.</param> 
    private void Initialize(MainWindowViewModel mainWindowViewModel) 
    { 
     //... 
     p_Log = new ObservableCollection<string>(); 
    } 

y luego los eventos definidos en ViewModelBase mantendrá la unión en la vista actualizada, sin necesidad de ningún código detrás en la vista en cualquier momento se añade una nueva cadena de la colección observable p_log.