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

Bat*_*bix 31 wpf

我正在尝试为WPF添加淡入淡出效果(动画)UserControls(尽管FrameworkElement为了使其更通用).

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

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

Iev*_*ida 19

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

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

  • 谢谢!对我的问题http://stackoverflow.com/q/18724686/352101非常有帮助 (2认同)

Riv*_*iva 13

多年来,但由于我现在正在寻找工作解决方案,因为现在是徒劳的,我想分享我的发现.

如果您想要ContentRendered任何Control(或任何Visual或甚至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'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;

    // ..
}
Run Code Online (Sandbox Code Playgroud)

您必须等待Control,Loaded否则PresentationSource.FromVisual()将返回null.

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

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

  • 不幸的是,`ContentRendered`仅在所有者`Window`第一次完成渲染时触发; 这意味着:如果在触发**`ContentRendered`之​​后,这个'UserControl`(或者其他`DependencyObject`)被渲染**,它将不会再次触发.当您有一些根据用户交互延迟加载的控件时,可能会遇到此问题. (3认同)

Ric*_*key 7

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

Dispatcher.BeginInvoke(BeginStoryboardAction, DispatcherPriority.ContextIdle);
Run Code Online (Sandbox Code Playgroud)

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


H.B*_*.B. 6

也许试试IsVisibleChanged,虽然我自己也没用过多少.

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


Mir*_*lal 5

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

MyUserControl.IsVisibleChanged += ScheduleUserControl_IsVisibleChanged;
Run Code Online (Sandbox Code Playgroud)

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

void _IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((bool)e.NewValue)
    {
        //Visible
    }
    else
    {
        //Not Visible
    }
}
Run Code Online (Sandbox Code Playgroud)