显示UserControl时会触发什么事件?

时间:2011-01-16 21:05:40

标签: wpf

我正在尝试为WPF UserControls添加淡入淡出效果(动画)(而不是FrameworkElement,以使其更通用)。

如果我让Loaded事件触发初始淡入,则淡入淡出动画有时会在UserControl显示之前启动。结果是一团糟。例如,如果UserControl在Loaded事件处理程序中执行冗长(十分之几秒),例如执行查询,则会发生这种情况。

因此,我需要处理一些在呈现内容时FrameworkElement / UserControl获取的事件,然后启动淡入。 System.Windows.WindowContentRendered个事件,但UserControl没有。那么,在渲染FrameworkElement(或UserControl)时会触发什么事件?

6 个答案:

答案 0 :(得分:19)

尝试在SizeChanged或LayoutUpdated上检查大小。当实际宽度或高度不等于0时执行。

view.LayoutUpdated+=(o,e)=>
{
  if (!loaded && (view.ActualHeight > 0 || view.ActualWidth > 0))
  {
     // You can also unsubscribe event here.
     loaded =true;
  }
}

答案 1 :(得分:13)

已经很晚了,但是因为我现在一直在找工作解决方案,但是我想分享我的发现。

如果您想要任何Control(或任何Visual或甚至DependencyObject)的ContentRendered事件,您必须深入研究Visual

我使用此代码:

// Wait for Control to Load
void TestUserControl_Loaded(object sender, RoutedEventArgs e)
{
    // Get PresentationSource
    PresentationSource presentationSource = PresentationSource.FromVisual((Visual)sender);

    // Subscribe to PresentationSource's 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()将返回null。

各种Dispatcher.BeginInvoke方法对我来说并不一致。有时在实际显示控件之前很久就会触发渲染事件 这对我来说每次都有用。

我知道我在这里玩HwndSource,这是一个非常低的水平,我不确定可能的影响。 (也许更有经验的人可以详细说明。)

答案 2 :(得分:6)

也许尝试IsVisibleChanged,但我自己并没有太多使用它。

  

如果元素未由布局系统呈现,则不会引发此事件,原因不是IsVisible属性的值。例如,元素可能没有关联的视觉效果。

答案 3 :(得分:6)

您可以安排优先级较低的Storyboard的开头,例如:

Dispatcher.BeginInvoke(BeginStoryboardAction, DispatcherPriority.ContextIdle);

这篇文章讨论了与使用此方法相关的问题:

答案 4 :(得分:4)

您可以使用IsVisibleChnaged事件 分配事件处理程序

MyUserControl.IsVisibleChanged += ScheduleUserControl_IsVisibleChanged;

在事件处理程序中检查if是否可见。

void _IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        //Visible
    }
    else
    {
        //Not Visible
    }
}

答案 5 :(得分:1)

您可以使用GotFocus事件

 <i:Interaction.Triggers>
        <i:EventTrigger EventName="GotFocus">
            <i:InvokeCommandAction Command="{Binding ContentControlLoadedCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>