DependencyProperty PropertyChangedCallback вызывает исключение NullReferenceException в XAML - PullRequest
0 голосов
/ 19 февраля 2010

У меня есть подкласс UserControl, который является содержимым моего главного окна. Я добавил DepedencyProperty в свой usercontrol типа ResizeMode, и обратный вызов PropertyChanged правильно устанавливает значение ResizeMode главного окна. Работает нормально. Я могу установить его из кода или из XAML, и он работает правильно. Однако, когда я устанавливаю его из XAML, дизайнер бросает ссылку Object, не установленную для экземпляра исключения объекта, в код в обратном вызове PropertyChanged, который устанавливает изменение размера окна.

<classes:MyUserControl ResizeMode="NoResize">
     <...>
</classes:MyUserControl>

Это обратный вызов. MainWindow - это ссылка на родительское окно.

private static void OnResizeModeChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
     (o as MyUserControl).MainWindow.ResizeMode = (ResizeMode) e.NewValue;
}

public ResizeMode ResizeMode
{
    get { return (ResizeMode) GetValue(ResizeModeProperty); }
    set { SetValue(ResizeModeProperty, value); }
}

public static readonly DependencyProperty ResizeModeProperty =
            DependencyProperty.Register("SizeToFit", typeof(ResizeMode), typeof(MyUserControl),
                new UIPropertyMetadata(ResizeMode.CanResize, new PropertyChangedCallback(OnResizeModeChanged)));

Я мог бы проигнорировать это или установить его в коде, но я не совсем понимаю причину этой ошибки, и я бы предпочел установить ее в XAML.

Может ли кто-нибудь пролить свет?

Ответы [ 2 ]

1 голос
/ 19 февраля 2010

Вы точно знаете, куда выбрасывается NullReferenceExceptoin?Например, если вы попробуете это вместо этого:

var uc = o as MyUserControl;
var mw = uc.MainWindow;

mw.ResizeMode = (ResizeMode)e.NewValue;

... тогда возникает ли исключение во второй строке или в третьей?

Мне кажется, что MainWindow не был назначенвремя, когда ResizeMode сначала получает значение, поэтому доступ к MainWindow.ResizeMode вызывает ошибку.

В этом случае можно игнорировать:

var mw = (o as MyUserControl).MainWindow;
if (mw == null) return;

Но вы можете кэшироватьгде-то значение, а затем назначьте его MainWindow.ResizeMode, когда MainWindow будет назначено позже.

0 голосов
/ 20 февраля 2010

ОК, я думаю, что нашел виновника. MainWindow устанавливается App.Current.MainWindow.

Теперь из того, что я прочитал, Current.MainWindow не существует во время разработки, а затем, когда во время разработки запускаются методы OnResizeModeChanged, MainWindow.ResizeMode, boom! Исключение!

Я добавил эту строку в мои методы:

if ((bool) (DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)) return;

Я столкнулся с другой проблемой, когда мой XAML внезапно не смог загрузить мой пользовательский контроль, потому что я установил некоторые свойства для MainWindow в конструкторе, добавил это:

 if (DesignerProperties.GetIsInDesignMode(this))
          return;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...