2009-07-13 9 views
1

J'ai un UserControl appelé SharpComboBox. J'utilise le modèle MVVM pour remplir le SharpComboBox avec des catégories. Pour cela, j'ai besoin de définir la propriété ItemsSource. Voici l'utilisation du contrôle SharpComboBox.Propriété de dépendance WPF retournant toujours NULL

<sharpControls:SharpComboBox ItemsSource="{Binding Path=Categories}" Grid.Column="1" Grid.Row="1" DisplayMemberPath="Title"> 

      </sharpControls:SharpComboBox> 

La fenêtre est appelée AddBook.xaml et voici le code derrière:

public AddBooks() 
     { 
      InitializeComponent(); 

      this.DataContext = new AddBookViewModel(); 

     } 

Et voici la mise en œuvre du AddBookViewModel.

public class AddBookViewModel 
    { 

     private CategoryRepository _categoryRepository; 

     public AddBookViewModel() 
     { 
      _categoryRepository = new CategoryRepository(); 
     } 



     public List<Category> Categories 
     { 
      get 
      { 
       return _categoryRepository.GetAll(); 
      } 
     } 

Et enfin voici le contrôle de SharpComboBox:

<StackPanel Name="stackPanel"> 
     <ComboBox x:Name="comboBox">  

      <ComboBox.ItemTemplate> 
       <DataTemplate> 
        <ItemsControl> 

         <Grid> 
          <Grid.ColumnDefinitions> 
           <ColumnDefinition Width="Auto"></ColumnDefinition> 
           <ColumnDefinition Width="2*"></ColumnDefinition> 
          </Grid.ColumnDefinitions> 

          <Grid.RowDefinitions> 
           <RowDefinition Height="Auto"></RowDefinition> 
          </Grid.RowDefinitions> 
         </Grid>             

         <TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding Path=Title}" Margin="10" /> 
         <Image Grid.Column="1" Margin="10" Grid.Row="0" Width="100" Height="100" Stretch="Fill" Source="{Binding Path=ImageUrl}"> 

         </Image>             


        </ItemsControl> 
       </DataTemplate> 
      </ComboBox.ItemTemplate> 


     </ComboBox> 

    </StackPanel> 

Et voici le code derrière:

public partial class SharpComboBox : UserControl 
    { 
     public static DependencyProperty ItemsSourceProperty; 

     public SharpComboBox() 
     { 
      InitializeComponent(); 
      this.DataContextChanged += new System.Windows.DependencyPropertyChangedEventHandler(SharpComboBox_DataContextChanged); 


      ItemsSourceProperty = DependencyProperty.Register("ItemsSource", typeof (IEnumerable), 
                   typeof (SharpComboBox), null); 

      comboBox.ItemsSource = ItemsSource; 
     } 

     public IEnumerable ItemsSource 
     { 
      get { return (IEnumerable) GetValue(ItemsSourceProperty); } 
      set { SetValue(ItemsSourceProperty, value); } 
     } 

     void SharpComboBox_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e) 
     { 

     } 

Pour une raison quelconque la propriété ItemsSource est toujours nulle.

mise à jour:

void SharpComboBox_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e) 
     { 
      var binding = new Binding(); 
      binding.Source = this.DataContext; 
      **binding.Path = new PropertyPath("Categories");** 
      comboBox.SetBinding(ComboBox.ItemsSourceProperty, binding); 
     } 
+0

Si vous devez référencer des contrôles sur votre View à partir de votre codebehind pour les forcer à s'actualiser, codemell pour votre liaison n'est pas correct ou vous ne notifiez pas la liaison qu'il doit être mis à jour en utilisant INotifyPropertyChanged. –

+0

Aussi, je vous encourage à regarder 0 codebehind étant votre objectif lorsque vous essayez de concevoir votre application avec MVVM. C'est entièrement possible. –

Répondre

0

Vous ne pouvez pas simplement régler la comboBox.ItemsSource de votre propriété une fois dans le constructeur, qui sait ce qui se passe tôt. Vous devez définir une liaison entre ces deux propriétés.

+0

Pouvez-vous donner un exemple ou modifier mon code pour refléter cela? – azamsharp

+0

J'ai mis à jour le code mais la propriété ItemsSource qui est ma propre propriété de dépendance retourne toujours null. – azamsharp

+0

Got it le code a été mis à jour! – azamsharp

2

kek444 est très proche, mais il manque un élément critique. J'ai remarqué que votre ViewModel n'implémente pas INotifyPropertyChanged. Cela empêchera les liaisons d'être actualisées automatiquement lorsque vous avez défini cette propriété. Ainsi, comme l'a mentionné kek444, vous êtes intiellement lié à null (parce que c'est tôt) et ensuite quand vous le définissez, vous n'informez pas votre vue du changement. C'est assez simple à changer, cependant.

public class AddBookViewModel : INotifyPropertyChanged 
{ 
    event PropertyChangedEventHandler PropertyChanged; 
    public AddBookViewModel() 
    { 
     _categoryRepository = new CategoryRepository(); 
     if(PropertyChanged != null) 
     { 
       PropertyChanged(this, new PropertyChangedEventArgs("Categories"); 
     } 
    } 
    ... 
} 

Chaque fois que vous modifiez votre magasin de sauvegarde (CategoryRepository), vous aurez envie de le faire. Il peut y avoir une complication supplémentaire en fonction de l'implémentation de votre référentiel, mais cette information devrait au moins expliquer ce qui se passe. En pratique, je crée généralement une classe ViewModel de base qui implémente INotifyPropertyChanged afin que je puisse ajouter quelques méthodes auxiliaires qui enveloppent cette logique PropertyChanged ... J'appelle simplement OnPropertyChanged ("MyProp"); et c'est tout.

Une autre chose qui pourrait vous aider est que les liaisons rapporteront à la sortie de débogage si vous les configurer correctement: Debugging WPF Binding

Hope this helps.

Questions connexes