PresentationSource.FromVisual(this) возвращает нулевое значение в WPF

Я использую следующий код для моего:

protected override void OnSourceInitialized(EventArgs e)
{
...
....
HwndSource source = PresentationSource.FromVisual(this) as HwndSource;
...
...
}

В некоторых системах «исходное» значение оказывается нулевым, и я не могу найти причину, по которой...


person AsitK    schedule 26.06.2012    source источник


Ответы (3)


Я думаю, вам, возможно, придется подождать, пока пользовательский интерфейс не отобразится, прежде чем вы попытаетесь назначить Hwnd. Вместо этого попробуйте поместить его в обработчик событий для Window.Loaded.

Это случалось со мной раньше, у меня было назначение Hwnd после того, как InitializeComponent() был вызван в конструкторе кода программной части. Он всегда возвращался нулевым, что может показаться, когда я прошел и увидел, что пользовательский интерфейс еще не появился. Я вставил его в обработчик _Loaded и вуаля, пользовательский интерфейс отображается до нажатия этой строки, и внезапно «это» перестало быть нулевым.

person WumpasTamer    schedule 21.10.2013

Начиная с .Net 4.0, вы можете получить доступ к HwndSource без предварительного отображения окна:

var helper = new WindowInteropHelper(this);
var hwndSource = HwndSource.FromHwnd(helper.EnsureHandle());
person Jan Gassen    schedule 06.07.2017
comment
Я все еще получаю null от PresentationSource.FromVisual после вызова WindowInteropHelper.EnsureHandle. Похоже, мне действительно нужно показать окно. FromVisual должен требовать других внутренних вещей, которые создаются лениво, помимо дескриптора. - person Drew Noakes; 07.01.2018
comment
Почему бы вам не использовать HwndSource.FromHwnd вместо этого? - person Jan Gassen; 07.01.2018
comment
Потому что мне нужен источник презентации для доступа к цели композиции для доступа к матрице для доступа к значениям DPI. - person Drew Noakes; 08.01.2018
comment
Не могли бы вы использовать new HwndTarget(helper.EnsureHandle()) для доступа к цели композиции и продолжить оттуда? - person Jan Gassen; 08.01.2018
comment
Интересная идея. Я реализовал обходной путь и пошел дальше, но время от времени сталкиваюсь с этим, поэтому попробую в следующий раз. Большое спасибо. - person Drew Noakes; 08.01.2018

Ответ WumpasTamer правильный. Я просто хотел бы добавить быстрый пример кода для всех, кто ищет решение «под ключ». Если вы уже используете WPF, то window не требуется, но если вы используете Winforms и хотите использовать PresentationSource, вам нужно будет использовать это.

void Main()
{
    var window = new Window
    {
        Width = 0,
        Height = 0,
        WindowStyle = WindowStyle.None,
        ShowInTaskbar = false,
        ShowActivated = false
    };
    window.Loaded += a_Loaded;
    window.Show();
}

void a_Loaded(object sender, EventArgs e)
{
    var s = (Window) sender;
    var source = PresentationSource.FromVisual(s);
    //...
    s.Close();
}
person The Muffin Man    schedule 23.04.2015