Пустая ссылка WPF Getting Control во время InitializeComponent - PullRequest
15 голосов
/ 25 марта 2010

Итак, мой вызов метода InitializeComponent в конструкторе Window выполняется через XML, добавляя элементы управления и вставляя их в свои события.

Таким образом, когда свойство одного из элементов управления изменяется, он вызывает метод, который подписывается на событие. Метод ссылается на элемент управления, который еще не был создан.

Почему это происходит в таком порядке здесь? Это работало в WinForms, потому что события не запускались до тех пор, пока не были созданы все элементы управления. Есть ли способ заставить это в WPF?

Другие решения, которые я вижу:

  • Мне нужно подписаться на события после инициализации.

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

Ответы [ 6 ]

28 голосов
/ 11 августа 2011

У меня тоже была эта проблема, и я решил ее, обернув строку, обращающуюся к элементу управления NULL, в проверку NULL. Это похоже на обходной путь.

Я думаю, что WPF пытается здесь помочь, вызывая наше событие Checked во время InitializeComponent (), чтобы гарантировать, что любая логика пользовательского интерфейса (например, отображение / скрытие связанных компонентов) выполняется на основе начального состояния флажка. Я проверил, что флажок не установлен по умолчанию, и обработчик событий не вызывается, даже если он связан с событиями Checked и Unchecked. Я даже воспроизвел это в пустом проекте WPF с одним флажком на экране, и он ведет себя так же.

Проблема с этим поведением по умолчанию, очевидно, заключается в том, что некоторые другие компоненты еще не инициализированы. Я думаю, что WPF должен подождать, пока все компоненты будут инициализированы, прежде чем запускать событие Checked по умолчанию. Это не может считаться ошибкой, но я все равно добавлю заметку на соответствующую страницу MSDN ...

5 голосов
/ 30 марта 2010

Это было событие Checked на радиокнопке. Когда я удалил Checked = "true" из xaml, проблема исчезла. (хотя проверяется при запуске окна). Не уверен, что здесь происходит, но, по крайней мере, мне не пришлось менять что-то серьезное, чтобы это исправить ... пока.

4 голосов
/ 25 марта 2010

Вы должны иметь возможность проверить свойства IsInitialized или IsLoaded в вашем окне, чтобы убедиться, что оно завершило инициализацию / загрузку. В противном случае вам нужно будет проверить наличие нулевых значений или добавить подписки на события в свой код (после InitializeComponent).

Кроме того, вы можете настроить способ доступа к элементам. Например, если у вас есть что-то вроде:

<ListBox x:Name="listBox" SelectionChanged="OnListBoxSelectionChanged" />

Тогда в вашем коде позади вы можете получить список несколькими способами:

private void OnListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) {
    ListBox lb = this.listBox; // May be null
    ListBox lb = sender as ListBox; // Should never be null
    ListBox lb = e.Source as ListBox; // Same as sender in this case
    ListBox lb = e.OriginalSource as ListBox; // Always the element that started the event (if handler is not attached directly to ListBox).
    // ... Do Something ...
}
1 голос
/ 30 июня 2016

У меня была такая же проблема, и я думаю, что это ошибка. Я нашел обходной путь, хотя: Я удалил 'Ischecked' из Xaml и установил его в коде после init

0 голосов
/ 17 июля 2012

Window Control генерирует события Checked при инициализации субэлементов управления, которые могут быть проверены и установлены в качестве начального значения.

Я твердо убежден, что это ошибка. Достаточно того, что он запускает исключение NullReferenceException из глубины сборки MFC, чтобы ожидать, что это непреднамеренное поведение.

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

Я имею в виду, должно ли оно запускать событие Unchecked, если вы установили его начальное состояние как unchecked?

0 голосов
/ 25 марта 2010

Использует ли какой-либо из элементов управления двустороннее связывание данных? Я столкнулся с этой проблемой, где у меня были текстовые поля, связанные со свойствами в ViewModel. Инициализация ViewModel запускала INotifyPropertyChanged вплоть до привязанного элемента управления, что, в свою очередь, вызывало событие TextChanged текстового поля. Мой краткосрочный обходной путь состоял в том, чтобы переместить подписку на событие в окно «Загруженное событие», но, как вы утверждаете, это своего рода боль. Мне нужно провести рефакторинг кода, чтобы изменить порядок инициализации моих объектов, чтобы представления WPF (т.е. окна и пользовательские элементы управления) создавались до ViewModels. Тогда я смогу перенести регистрацию обработчика событий обратно в XAML.

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