wpf 在 Loaded 事件中渲染未完成

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19684191/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:59:00  来源:igfitidea点击:

Rendering not finished in Loaded event

wpfanimationopacityloaded

提问by Gerard

I subscribed to the wpf window's Loaded event: Loaded += loaded;and try to change the opacity of some controls in code behind.
I notice that in the method loadedthe controls are not painted by wpf yet. So the code has no effect, the rendering of the controls occurs only after the method is exited.

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

1) Is there another event e.g. Renderedthat I can subscribe to?

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

EDIT: I just discovered that there is an OnContentRendered event and the following code works:
Although an animation is probably preferrable.

编辑:我刚刚发现有一个 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);
   }
}

Otherwise I probably have to use an animation that changes the opacity of usercontrol1 from 0.1 to 1.0 and of usercontrol2 from 1.0 to 0.0.

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

2) Do you know an example for such an animation?

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

回答by majocha

In your Loaded handler you can post the UI altering operation ( e.g. void ChangeOpacity()) on the dispatcher:

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

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

It will execute after the rendering is done.

它会在渲染完成后执行。

Edit

编辑

I see you simply need an animation to start when the window opens. It's easily done in XAML, here's a working example generated in Blend:

我看到您只需要在窗口打开时启动动画即可。它在 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>

回答by DRapp

I just recently was having issues while trying to render some standardized animation to WPF usercontrols when the visibility changed. In my app, I have a couple singleton static classes. In one, I added a static method "VisibleFader" and you pass in the framework element control and it automatically attaches the event handler to the double-animation against the opacity property. It works great and does not require ANY changes to any other Styles, Control Templates, or any other theme implementations.

我最近在尝试将一些标准化动画呈现给 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);
}

Then, in my class (such as your Loaded Event), I just call this static method with that "userControl" object.

然后,在我的类(例如您的 Loaded Event)中,我只是使用该“userControl”对象调用此静态方法。

MySingletonClass.VisibleFader( this.whateverUserControl );

Done... So, when the visibility changes, it fades IN from nothing to 1. And if something was having its visibilty to hidden, it's gone anyhow.

完成... 所以,当可见性改变时,它从无到 1 逐渐淡入。如果某些东西的可见性被隐藏,它无论如何都消失了。