Какое событие запускается при отображении UserControl?
Я пытаюсь добавить эффект Fade (анимация) для WPF UserControls
(хотя скорее для FrameworkElement
, чтобы сделать его более общим).
Если я позволяю событию Loaded
инициировать начальное затухание, анимация затухания иногда запускается до отображения UserControl. Результат - беспорядок. Это происходит, например, если UserControl делает что-то длинное (несколько десятых доли секунды), например выполнение запроса, в обработчике событий Loaded.
Итак, мне нужно будет обработать какое-то событие, которое получит FrameworkElement/UserControl, когда содержимое будет отображено, и затем запустите его. System.Windows.Window
имеет событие ContentRendered
, но UserControl этого не делает. Итак, какое событие вызывается, когда рендеринг FrameworkElement (или UserControl)?
Ответы
Ответ 1
Попробуйте проверить размер на SizeChanged или LayoutUpdated. Выполнять работу, когда фактическая ширина или высота не равна 0.
view.LayoutUpdated+=(o,e)=>
{
if (!loaded && (view.ActualHeight > 0 || view.ActualWidth > 0))
{
// You can also unsubscribe event here.
loaded =true;
}
}
Ответ 2
Спустя годы, но так как я тщетно искал рабочее решение, я хочу поделиться своим открытием.
Если вы хотите событие ContentRendered
для любого ContentRendered
управления (или любого визуального или даже DependencyObject), вам нужно перейти к Visual
.
Я использую этот код:
// Wait for Control to Load
void TestUserControl_Loaded(object sender, RoutedEventArgs e)
{
// Get PresentationSource
PresentationSource presentationSource = PresentationSource.FromVisual((Visual)sender);
// Subscribe to PresentationSource ContentRendered event
presentationSource.ContentRendered += TestUserControl_ContentRendered;
}
void TestUserControl_ContentRendered(object sender, EventArgs e)
{
// Don't forget to unsubscribe from the event
((PresentationSource)sender).ContentRendered -= TestUserControl_ContentRendered;
// ..
}
Вы должны ждать Control Loaded
иначе PresentationSource.FromVisual() возвращает ноль.
Различные методы Dispatcher.BeginInvoke не помогли мне постоянно. Иногда запускаю мое визуализированное событие задолго до того, как элемент управления будет отображаться.
Это работает для меня каждый раз.
Я знаю, что я играю здесь с HwndSource, который является довольно низким уровнем, и я не уверен в возможных последствиях. (Может быть, кто-то более опытный может уточнить.)
Ответ 3
Может быть, попробуйте IsVisibleChanged
, но я не использовал его сам.
Это событие не возникает, если элемент не отображается системой компоновки по причинам, отличным от значения свойства IsVisible. Например, элемент может не иметь связанного с ним изображения.
Ответ 4
Вы можете запланировать начало вашего Storyboard
с более низким приоритетом, например:
Dispatcher.BeginInvoke(BeginStoryboardAction, DispatcherPriority.ContextIdle);
Здесь описывается проблема, связанная с использованием этого метода:
Ответ 5
Вы можете использовать событие IsVisibleCnaged
Назначить обработчик событий
MyUserControl.IsVisibleChanged += ScheduleUserControl_IsVisibleChanged;
В случае, если обработчик проверки, если он виден или нет.
void _IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue)
{
//Visible
}
else
{
//Not Visible
}
}
Ответ 6
Вы можете использовать событие GotFocus
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<i:InvokeCommandAction Command="{Binding ContentControlLoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Ответ 7
Я не могу дать ответ - из-за моей репутации, но мне нужно расширить этот пост
Какое событие вызывается при отображении UserControl?
Прежде всего - это мне очень помогло. Чтобы убедиться, что он полностью отрисован, добавьте IsLoaded
в оператор if