SizeToContent для Window: медленная загрузка приводит к тому, что окно отображается маленьким, ТОГДА изменяет размер правильно - PullRequest
1 голос
/ 14 марта 2011

Хорошо, поэтому у меня есть окно, которое появляется ( во время нормальной работы программы ) по запросу пользователя, чтобы отобразить некоторую контекстно-зависимую информацию.В этом окне много элементов, поэтому загрузка занимает 0,5 - 1 сек.Однако, поскольку я ожидаю, что это окно будет содержать несколько различных типов информации в зависимости от контекста, ширина и высота его содержимого могут различаться.Таким образом, я установил значение SizeToContent на «WidthAndHeight», чтобы разрешить изменение размера окна в зависимости от того, какой контент связан с ним.

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

Есть ли способ заставить окно отображать только ПОСЛЕ того, как оно полностью отрисовалось?

Что я пробовал:

  • установить видимость окна на «Скрытый» и затем установить его на «Видимый» в обработчике событий ContentRendered: окно никогда не отображалось.

  • установить непрозрачность окнав 0, а затем установите его в 1 в обработчике событий ContentRendered: непрозрачность содержимого в самом окне устанавливается в 0, затем в 1.

Обновление: еще одна попытка

Я также попытался установить Window.WindowState в значение «Minimized» в XAML, а затем установить его в «Normal» в обработчике событий ContentRendered.Кажется, это работает частично, хотя ширина самого окна больше, чем должна быть.Хуже того, кажется, что содержимое в окне отображается в соответствии с правильным размером для окна, а затем окно становится больше без повторной визуализации содержимого.Таким образом, содержимое не центрируется в окне, и у нас есть неприятный черный прямоугольник справа от содержимого, который представляет собой разницу между правильным размером окна и текущим (большим) размером.Когда я изменяю размер окна вручную, захватывая край окна, содержимое перерисовывается правильно, и все выглядит хорошо.Но как заставить такой повторный рендеринг в коде?Window.UpdateLayout () не работает.

Ответы [ 3 ]

1 голос
/ 14 марта 2011

Хорошо, я нашел решение, которое работает. Не идеально, но это работает.

Сначала я установил Window.WindowState на «Свернутый» в XAML. Это предотвращает появление окна на экране во время рендеринга. Затем я подписался на событие ContentRendered для окна и добавил в обработчик следующий код:

this.WindowState = System.Windows.WindowState.Normal;
this.MaxWidth = MainContentPresenter.ActualWidth;
this.Height = MainContentPresenter.ActualHeight;

this.InvalidateVisual();

где MainContentPresenter - это ContentPresenter для окна. ViewModel привязан к этому элементу, поэтому там отображается его содержимое.

0 голосов
/ 16 марта 2011

Хорошо, я нашел свою ошибку. SizeToContent, установленный в WidthAndHeight, работает нормально, пока DataContext для нового окна был установлен ДО , когда вы открываете окно. Как в:

secondaryWindow.DataContext = viewModel;  

secondaryWindow.Show();

вместо:

secondaryWindow.Show();

secondaryWindow.DataContext = viewModel;  

как у меня.

Так что происходило то, что размер окна подходил в случае, когда DataContext был нулевым, а затем изменял размер, когда был установлен DataContext.

Спасибо Elad Katz за добавление решения, которое косвенно заставило меня найти эту ошибку.

0 голосов
/ 15 марта 2011

Обратите внимание, что вы можете знать, какому размеру окна требуется событие, не показывая его вообще.

Если у вас есть элемент управления, который вы хотите знать, какого размера он хочет, вы можете сделать следующее

// I'm picking Button here, but any control could be put here, be it
// Window or whatever:

Button b = new Button();

// I'm putting some content to see that it actually measures it children. If you'll put more text here
// you'll see bigger size
b.Content = "Hello";

// I'm manually measuring the control, passing in double.PositiveInfinity so that the control
// would give me the size it wants, regardless of any constraints (you can put constraints here
// if you like)
b.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));

// After Measure is called, the Property DesiredSize become relevant, and contains the size that the
// Control needs to show all of its contents.
MessageBox.Show(b.DesiredSize.ToString());
...