2009-07-13 11 views
1

Ich habe ein UserControl namens SharpComboBox. Ich benutze MVVM-Modell, um die SharpComboBox mit Kategorien aufzufüllen. Dafür muss ich die ItemsSource-Eigenschaft festlegen. Hier ist die Verwendung des SharpComboBox-Steuerelements.Abhängigkeitseigenschaft WPF, die immer NULL zurückgibt

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

      </sharpControls:SharpComboBox> 

Das Fenster ist das AddBook.xaml genannt und hier ist der Code hinter:

public AddBooks() 
     { 
      InitializeComponent(); 

      this.DataContext = new AddBookViewModel(); 

     } 

Und hier ist die Umsetzung des AddBookViewModel.

public class AddBookViewModel 
    { 

     private CategoryRepository _categoryRepository; 

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



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

Und schließlich ist hier die SharpComboBox Kontrolle:

<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> 

Und hier ist der Code hinter:

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) 
     { 

     } 

Aus irgendeinem Grund die Itemssource-Eigenschaft immer null ist.

AKTUALISIERT:

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

Wenn Sie die Steuerelemente in Ihrer Sicht von Ihrem Codebehind aus referenzieren müssen, um sie zu aktualisieren, ist dies ein Codesmell, wenn Ihre Bindung nicht korrekt ist oder Sie die Bindung nicht mit INotifyPropertyChanged aktualisieren. –

+0

Außerdem würde ich Sie ermutigen, zu betrachten 0 codebehind, Ihr Ziel zu sein, wenn Sie versuchen, Ihre Anwendung mit MVVM zu entwerfen. Es ist durchaus möglich. –

Antwort

0

Sie können nicht einfach die comboBox.ItemsSource aus Ihrer Immobilie einmal im Konstruktor festgelegt, wer weiß, wie früh das passiert. Sie müssen eine Bindung zwischen diesen beiden Eigenschaften festlegen.

+0

Können Sie meinen Code angeben oder bearbeiten, um das widerzuspiegeln? – azamsharp

+0

Ich habe den Code aktualisiert, aber die ItemsSource, die meine eigene Abhängigkeitseigenschaft ist, gibt immer null zurück. – azamsharp

+0

Der Code wurde aktualisiert! – azamsharp

2

kek444 ist sehr nah, aber es gibt ein kritisches Element fehlt. Ich habe festgestellt, dass Ihr ViewModel INotifyPropertyChanged nicht implementiert. Dies verhindert, dass Bindungen automatisch aktualisiert werden, wenn Sie diese Eigenschaft festgelegt haben. So, wie kek444 erwähnt, binden Sie sich anfänglich an Null (weil es früh ist) und wenn Sie es dann festlegen, informieren Sie Ihre Ansicht der Änderung nicht. Es ist jedoch ziemlich einfach zu ändern.

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

Jedes Mal, wenn Sie Ihren Backstore (CategoryRepository) ändern, sollten Sie dies tun. Es kann einige zusätzliche Komplikationen geben, abhängig davon, ob Ihr Repository implementiert ist, aber diese Informationen sollten zumindest erklären, was vor sich geht.

Als eine Praxis, erzeuge ich im Allgemeinen eine Base ViewModel-Klasse, die INotifyPropertyChanged implementiert, so dass ich einige Hilfsmethoden hinzufügen kann, die diese PropertyChanged-Logik umhüllen ... Ich rufe OnPropertyChanged ("MyProp"); und das ist es.

Eine andere Sache, die Ihnen helfen könnte, ist, dass Bindungen an die Debug-Ausgabe berichten, wenn man sie richtig konfiguriert: Debugging WPF Binding

Hoffnung, das hilft.

Verwandte Themen