在 Loaded 事件中未完成渲染

Posted

技术标签:

【中文标题】在 Loaded 事件中未完成渲染【英文标题】:Rendering not finished in Loaded event 【发布时间】:2013-11-10 03:23:02 【问题描述】:

我订阅了 wpf 窗口的 Loaded 事件:Loaded += loaded; 并尝试在后面的代码中更改某些控件的不透明度。 我注意到在loaded 方法中,wpf 尚未绘制控件。所以代码没有效果,控件的渲染只有在方法退出后才会发生。

1) 是否还有其他事件,例如? Rendered 可以订阅吗?

编辑:我刚刚发现有一个 OnContentRendered 事件并且以下代码有效: 虽然动画可能更可取。

protected override void OnContentRendered(EventArgs e)

   base.OnContentRendered(e);
   for (int i = 0; i < 100; i++)
   
       Parentpanel.Opacity += 0.01;
       Splashscreen.Opacity -= 0.01;
       Dispatcher.Invoke(new Action(() =>  ), DispatcherPriority.ContextIdle, null);
       Thread.Sleep(50);
   

否则我可能不得不使用将 usercontrol1 的不透明度从 0.1 更改为 1.0 并将 usercontrol2 从 1.0 更改为 0.0 的动画。

2) 你知道这样一个动画的例子吗?

【问题讨论】:

您的控件在哪里定义?例如,如果它们在ControlTemplate 中定义,那么在引发Loaded 事件时它们可能还没有准备好。在这种情况下,您需要处理FrameworkElement.OnApplyTemplate Method。 【参考方案1】:

在您的 Loaded 处理程序中,您可以在调度程序上发布 UI 更改操作(例如 void ChangeOpacity()):

Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(ChangeOpacity));

渲染完成后执行。

编辑

我看到您只需要在窗口打开时启动动画即可。在 XAML 中很容易完成,这是在 Blend 中生成的一个工作示例:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="100" Width="200">
    <Window.Resources>
        <Storyboard x:Key="myStoryboard">
            <DoubleAnimationUsingKeyFrames
                         Storyboard.TargetProperty="(UIElement.Opacity)"
                         Storyboard.TargetName="myControl">
                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>
    <Window.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="StaticResource myStoryboard"/>
        </EventTrigger>
    </Window.Triggers>
    <StackPanel>
        <TextBox x:Name="myControl" Text="I'm disappearing..." />
    </StackPanel>
</Window>

【讨论】:

正确,您的调度程序看起来比我的想法 OnContentRendered 更好,尽管在每一步之后必须调用调度程序进行刷新。动画效果更好,看起来更好。 这对我很有用,谢谢。对我来说等效的 Visual Basic .NET 4.5.1 是:Dispatcher.BeginInvoke(New Action(AddressOf methodName), Windows.Threading.DispatcherPriority.Loaded)【参考方案2】:

我最近在尝试将一些标准化动画呈现给 WPF 用户控件时遇到了问题,因为可见性发生了变化。在我的应用程序中,我有几个单例静态类。一方面,我添加了一个静态方法“VisibleFader”,您传入框架元素控件,它会自动将事件处理程序附加到针对 opacity 属性的双动画。它运行良好,不需要对任何其他样式、控件模板或任何其他主题实现进行任何更改。

public static DoubleAnimation da;
public static void VisibleFader(FrameworkElement fe)

   if (da == null)
   
      da = new DoubleAnimation();
      da.From = 0;
      da.To = 1;
      da.Duration = new Duration(TimeSpan.FromSeconds(.7));
   

   fe.IsVisibleChanged += myFader;


private static void myFader(object sender, DependencyPropertyChangedEventArgs e)

   ((FrameworkElement)sender).BeginAnimation(FrameworkElement.OpacityProperty, da);

然后,在我的类(比如你的 Loaded Event)中,我只是用那个“userControl”对象调用这个静态方法。

MySingletonClass.VisibleFader( this.whateverUserControl );

完成...因此,当可见性发生变化时,它会从无到 1 淡入。如果某物的可见性被隐藏,无论如何它都消失了。

【讨论】:

我稍后会研究这个,看起来很有希望,顺便看看我的编辑。

以上是关于在 Loaded 事件中未完成渲染的主要内容,如果未能解决你的问题,请参考以下文章

从自动完成下拉列表中未选择任何选项时如何清除 mat- 自动完成

PhoneGap / Cordova 回调错误 - 在 PhoneGap 中未执行 RestKit 完成功能

iOS 模拟器中未显示游戏中心完成横幅

如何判断WPF下窗口加载完成了

DispatchQueue.main.async 块中未更新完成处理程序的返回值

CFStream Socket 发送数据包在 IOS 7.0 中未完成