Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rendering not finished in Loaded event

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 loaded the 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.

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

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

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.

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

like image 561
Gerard Avatar asked Jan 12 '23 00:01

Gerard


2 Answers

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

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:

<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>
like image 69
majocha Avatar answered Jan 24 '23 04:01

majocha


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.

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.

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.

like image 23
DRapp Avatar answered Jan 24 '23 06:01

DRapp