Domanda Quale evento viene generato quando viene visualizzato un UserControl?


Sto cercando di aggiungere un effetto di dissolvenza (animazione) per WPF UserControls (anche se piuttosto per FrameworkElement, per renderlo più generale).

Se lascio il Loaded evento innescare la dissolvenza iniziale, l'animazione di dissolvenza a volte è iniziata prima che l'UserControl sia stato visualizzato. Il risultato è un casino. Ciò accade ad esempio se UserControl fa qualcosa di lungo (pochi decimi di secondo), come eseguire una query, nel gestore di eventi Loaded.

Quindi, avrei bisogno di gestire alcuni eventi che FrameworkElement / UserControl ottiene quando il contenuto è stato reso, e quindi avviare la dissolvenza in apertura. Il System.Windows.Window ha un ContentRendered evento, ma UserControl no. Quindi, quale evento viene generato quando viene eseguito il rendering di FrameworkElement (o UserControl)?


26
2018-01-16 21:05


origine


risposte:


Prova a controllare le dimensioni su SizeChanged o LayoutUpdated. Fai un lavoro quando larghezza o altezza effettive non è uguale a 0.

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

18
2017-09-02 09:01



Anni di ritardo, ma dal momento che cercavo soluzioni di lavoro da ora invano, voglio condividere la mia scoperta.

Se vuoi un ContentRendered evento per qualsiasi Controllo (o qualsiasi Visual o anche DependencyObject), devi scavare verso il basso Visual.

Io uso questo codice:

// 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 -= testContentRenderedUC_ContentRendered;

    // ..
}

Devi aspettare il controllo Loaded altrimenti PresentationSource.FromVisual () restituisce null.

I vari metodi di Dispatcher.BeginInvoke non hanno funzionato in modo coerente per me. A volte sparava il mio evento renderizzato molto prima che il controllo fosse effettivamente visualizzato.
Questo funziona per me ogni volta.

Sono consapevole che sto giocando con HwndSource qui, che è piuttosto basso e non sono sicuro delle possibili implicazioni. (Forse qualcuno più esperto può elaborare).


11
2018-06-29 20:59



Forse prova IsVisibleChangedcomunque non l'ho usato molto

Questo evento non viene generato se l'elemento non viene sottoposto a rendering dal sistema di layout, per motivi diversi dal valore della proprietà IsVisible. Ad esempio, l'elemento potrebbe non avere una vista associata.


6
2018-01-16 21:09



Puoi pianificare l'inizio del tuo Storyboard con una priorità più bassa, ad esempio:

Dispatcher.BeginInvoke(BeginStoryboardAction, DispatcherPriority.ContextIdle);

Ecco un articolo che illustra i problemi relativi all'utilizzo di questo metodo:


6
2018-01-16 21:23



È possibile utilizzare l'evento IsVisibleChnaged Assegna il gestore di eventi

MyUserControl.IsVisibleChanged += ScheduleUserControl_IsVisibleChanged;

Nel gestore eventi controllare se è visibile o meno.

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

4
2017-12-08 16:12



È possibile utilizzare l'evento GotFocus

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

1
2018-03-09 08:34