Наличие владельца окна настройки проблемы в родительском конструкторе
Что-то не так в WPF с установкой свойства владельца окна его родительскому объекту в этом родительском конструкторе? Не должно быть, правда? Итак, почему я получаю XamlParseException
из следующего кода?
public partial class MainView : Window
{
private readonly OwnedWindow owned;
public MainView()
{
InitializeComponent();
owned = new OwnedWindow();
owned.DataContext = DataContext;
var window = GetWindow(this);
owned.Owner = this; //Setting to window causes the same error
...
}
Я должен пояснить, что удаление owned.Owner = this;
также устраняет ошибку времени выполнения.
Сведения об исключении:
Исключение XamlParseException было необработанным
Вызов конструктора по типу "... MainView", который соответствует указанные ограничения привязки вызывают исключение.
Собственно, я посмотрел на Внутреннее Исключение, и он говорит:
Невозможно установить свойство Owner в окно, которое не было показано ранее.
Итак, я изучаю это сейчас.
Ответы
Ответ 1
Проблема заключается в том, что, поскольку WPF создает только собственное окно при первом показе окна WPF, вы не можете установить окно, пока еще не показанное как Owner
(так как это устанавливает владельца собственного окна → owned ", но встроенный дескриптор еще не существует.)
Вы можете обработать событие StateChanged
в окне владельца, убедиться, что новое состояние "показано", а затем установить соответствующее окно Owner
в этой точке. В качестве альтернативы вы можете создать и показать окно, находящееся в этом месте.
Ответ 2
Я подписался на Window.Activated
, а не Window.StateChanged
. Обязательно отпишитесь на него в обработчике, как указано в комментариях.
private void OnActivated(object sender, EventArgs eventArgs)
{
owned.Owner = this;
Activated -= OnActivated;
}
Я принял ответ dlev, потому что это привело меня непосредственно к поиску ответа, даже если он не работал для моей точной ситуации.
Ответ 3
Вам нужен WPF-эквивалент события HandleCreated
, который равен SourceInitialized
. Это должно работать:
public OwnerWindow()
{
InitializeComponent();
SourceInitialized += (s, a) =>
{
var owned = new OwnedWindow();
owned.Owner = this;
};
}
Обратите внимание, что для этого вам не нужно Show
использовать OwnWindow или OwnedWindow.