Проблемы привязки пользовательского элемента управления WPF MVVM - PullRequest
2 голосов
/ 11 ноября 2009

У меня есть приложение, которое использует MVVM. У меня есть несколько элементов в главном окне, которые связаны с ViewModel для этого окна. Когда я запускаю это все работает. Однако, когда я добавляю пользовательский элемент управления в главное окно и пытаюсь привязать его к одному из его объектов зависимостей, он выдает исключение («Ссылка на объект не установлена ​​для экземпляра объекта»). Окно исключений просто появляется на экране и не ссылается на какое-либо конкретное место в коде. И любая другая информация в исключении не является полезной.

Я старался изо всех сил отследить это, но мне не повезло. В конструкторе окна я проверил и подтвердил, что элемент, к которому он пытается привязаться, существует и является объектом (int []). Я также вручную установил свойство в конструкторе с проблемами. Вот некоторые фрагменты кода, если кто-нибудь может заметить что-либо.

Здесь я использую пользовательский элемент управления и пытаюсь привязать свойство 'view'

<local:Histogram Grid.Row="2" Grid.ColumnSpan="2"
                                        View="{Binding Path=HistogramData}"             
                                        Foreground="{DynamicResource FontColor}"
                                        BucketStroke="{DynamicResource BucketStrokeBrush}"
                                        BucketFill="{DynamicResource BucketFillBrush}"
                                        SelectedBrush="{DynamicResource FamilyEditListViewSelectedBrush}"
                                        DisabledForegroundBrush="{DynamicResource DisabledForegroundBrush}"
                                        AxisBrush="{DynamicResource AxisBrush}" 
                                        MaxHeight="130" />

Вот поле в модели представления, к которому я пытаюсь привязаться:

public int[] HistogramData
    {
        get
        {
            return histogramData;
        }
        set
        {
            if (value != histogramData)
            {
                histogramData = value;
                RaisePropertyChanged("HistogramData");
            }
        }
    }

И в конструкторе модели представления я создаю экземпляр объекта

histogramData = new int[256];

И, наконец, вот свойство view в пользовательском элементе управления

public static readonly DependencyProperty ViewProperty =
        DependencyProperty.Register("View", 
                                    typeof(int[]), 
                                    typeof(Histogram),
                                    new FrameworkPropertyMetadata(null,
                                                                  FrameworkPropertyMetadataOptions.AffectsRender,
                                                                  new PropertyChangedCallback(ViewProperty_Changed)));

    public int[] View
    {
        get { return (int[])GetValue(ViewProperty); }
        set { SetValue(ViewProperty, value); }
    }

Я не знаю, достаточно ли этой информации, чтобы что-то решить, поэтому, если требуется больше кода, пожалуйста, сообщите мне. Я мог бы также сжать проект, если кто-то так склонен смотреть на это. Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 16 ноября 2009

Вы можете попробовать инициализировать массив при инициализации FrameworkPropertyMetaData для свойства зависимостей.

 new FrameworkPropertyMetadata(new int [256],
                              FrameworkPropertyMetadataOptions.AffectsRender,  
                              new PropertyChangedCallback(ViewProperty_Changed))

Я думаю, что программа может выполнить исключение нулевой ссылки, прежде чем ей удастся связать свойство зависимости со свойством viewmodel.


Хорошо, я посмотрел ваш пример проекта и думаю, что у меня есть решение.

изменить int[] в модели представления на List<int>. Я не уверен, почему это работает. Я надеюсь, что нет технической причины, по которой list<int> вам не подходит.

Вот что я изменил в решении

в модели просмотра

public List<int> CustomData
        {
            get
            {
                return new List<int>(){0,1,2,3};
            }
            set
            {
            }
        }

В массиве кода управления позади

public static readonly DependencyProperty DataProperty =
            DependencyProperty.Register("Data",
                                        typeof(List<int>),
                                        typeof(ArrayControl),
                                        new FrameworkPropertyMetadata(new List<int>()));

        public List<int> Data
        {
            get { return (List<int>)GetValue(DataProperty); }
            set { SetValue(DataProperty, value); }
        }

В arraycontrol.xaml. Просто добавлен список для отображения работающей привязки данных

<UserControl x:Class="UserControlWithArray.Controls.ArrayControl"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="300" Width="300">
    <Grid>
             <TextBlock x:Name="MessageTextBlock" Text="ArrayControl"/> 
        <ListBox ItemsSource="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}, Path=Data}"/>
    </Grid>
</UserControl>
1 голос
/ 11 ноября 2009

Используйте отладчик, чтобы получить трассировку стека исключений. Это должно помочь вам сузить проблему.

Есть несколько способов сделать это. Например, вы должны иметь возможность просто просмотреть детали исключения. Или вы можете открыть окно просмотра и ввести выражение $exception, а затем нажать «Оценить».

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