Свойство зависимости WPF, всегда возвращающее NULL - PullRequest
1 голос
/ 13 июля 2009

У меня есть UserControl под названием SharpComboBox. Я использую модель MVVM для заполнения SharpComboBox категориями. Для этого мне нужно установить свойство ItemsSource. Вот использование элемента управления SharpComboBox.

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

            </sharpControls:SharpComboBox>

Окно называется AddBook.xaml, и вот код:

 public AddBooks()
        {
            InitializeComponent();

            this.DataContext = new AddBookViewModel(); 

        }

А вот и реализация AddBookViewModel.

 public class AddBookViewModel
    {

        private CategoryRepository _categoryRepository; 

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



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

И, наконец, вот элемент управления 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>

А вот код:

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

        }

По какой-то причине свойство ItemsSource всегда имеет значение null.

ОБНОВЛЕНО:

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

Ответы [ 2 ]

2 голосов
/ 13 июля 2009

kek444 очень близко, но отсутствует один критический элемент. Я заметил, что ваша ViewModel не реализует INotifyPropertyChanged. Это предотвратит автоматическое обновление привязок при установке этого свойства. Итак, как упомянул kek444, вы изначально привязаны к нулю (потому что это рано), а затем, когда вы устанавливаете его, вы не информируете свое мнение об изменении. Это довольно просто изменить.

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

Каждый раз, когда вы меняете свой резервный магазин (CategoryRepository), вы захотите это сделать. Здесь могут быть некоторые дополнительные сложности в зависимости от того, реализован ли ваш репозиторий, но эта информация должна хотя бы объяснить, что происходит.

На практике я обычно создаю базовый класс ViewModel, который реализует INotifyPropertyChanged, поэтому я могу добавить несколько вспомогательных методов, которые обертывают эту логику PropertyChanged ... Я просто вызываю OnPropertyChanged ("MyProp"); и это все.

Еще одна вещь, которая может вам помочь, это то, что привязки будут сообщать в выходные данные отладки, если вы настроите их правильно: Отладка привязки WPF

Надеюсь, это поможет.

0 голосов
/ 13 июля 2009

Вы не можете просто установить comboBox.ItemsSource из своего свойства один раз в конструкторе, который знает, как рано это происходит. Вам необходимо установить привязку между этими двумя свойствами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...