2013-10-16 7 views
5

Ich habe ein Gitter, das, wenn man mit der Maus darüber fährt, eines seiner Kindelemente zum Leben erweckt (Deckkraft von 0 bis 1), aber dieses Gitter kann auch entsorgt werden (das Raster ist Teil einer Listbox, die über eine Schließen-Schaltfläche im Raster entfernt werden kann).Block MouseLeave trigger wenn Objekt entsorgt wird

Wenn der Benutzer auf die Schaltfläche zum Entfernen klickt, wird auch das MouseLeave-Ereignis ausgelöst, unter dem mein DockStackPanel-Steuerelement seit seiner Entsorgung natürlich nicht mehr gefunden werden kann. Wie kann ich dieses Problem beheben?

 <Grid.Triggers> 
     <EventTrigger RoutedEvent="UIElement.MouseEnter"> 
      <BeginStoryboard> 
       <Storyboard> 
        <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="DockStackPanel" Storyboard.TargetProperty="Opacity" To="1" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
     <EventTrigger RoutedEvent="UIElement.MouseLeave"> 
      <BeginStoryboard> 
       <Storyboard> 
        <DoubleAnimation Duration="0:0:0.5" Storyboard.TargetName="DockStackPanel" Storyboard.TargetProperty="Opacity" To="0" /> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Grid.Triggers> 
+1

Sie gehen zu müssen, etwas mehr Code Chef schreiben. –

Antwort

2

Haben Sie versucht, die Animation stattdessen in Code zu erstellen. Ich gehe hier davon aus, dass das DockStackPanel-Steuerelement ein StackPanel ist.

public MainWindow() 
    { 
     InitializeComponent(); 

     MyGrid.MouseEnter += MyGrid_MouseEnter; 
     MyGrid.MouseLeave += MyGrid_MouseLeave; 
    } 

    void MyGrid_MouseLeave(object sender, MouseEventArgs e) 
    { 
     if (DockStackPanel != null) 
     { 
      var dur = new Duration(new TimeSpan(0, 0, 0, 0, 500)); 
      var anim = new DoubleAnimation(0, dur); 
      DockStackPanel.BeginAnimation(StackPanel.OpacityProperty, anim); 
     } 
    } 

    void MyGrid_MouseEnter(object sender, MouseEventArgs e) 
    { 
     var dur = new Duration(new TimeSpan(0, 0, 0, 0, 500)); 
     var anim = new DoubleAnimation(1, dur); 
     DockStackPanel.BeginAnimation(StackPanel.OpacityProperty, anim); 
    } 
+0

Ich hüpfte, um Code hinterher zu vermeiden, aber es scheint die beste Lösung zu sein, also danke! – touyets

+0

Kein Problem, froh zu helfen – snacky

1

Eine andere Sache, die Sie tun können, ist DataTrigger für Grid zu implementieren, die Standard MouseLeave und MouseEnter Ereignisse außer Kraft gesetzt wird, wenn nichts DisableTriggers Eigenschaft geändert zu tun.

<Style TargetType="{x:Type Grid}"> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding DisableTriggers}" Value="True"> 
      <Setter Property="Style" Value="{StaticResource GridStyleWithoutStoryboards}" /> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

Dies ist der Fall, wenn Sie nicht AttachedBehaviors verwenden möchten. Ansonsten schlage ich vor, Storyboards im Verhalten zu bereinigen. Es ist viel einfacher:

void OnDisableTriggersPropertyChanged(object sender, EventArgs args) 
{ 
    // If IsDisposed property was changed and it is true now - cleanup triggers. 
    if ((bool)args.NewValue) 
    { 
     var grid = (Grid)sender; 

     // Ideally you can remove specific triggers. 
     // Clear all will work for simple cases. 
     grid.Triggers.Clear(); 
    } 
} 

Summieren Sie werden also angebracht Verhalten mit DisableTriggers Abhängigkeitseigenschaft hinzufügen, um die Bereinigung Aktion in OnChanged Handler ausführt.

Wenn Sie nur von bestimmten Ereignissen annullieren:

foreach (var eventToUnsubscribe in grid.Triggers.OfType<EventTrigger>() 
                .Where(x => x.RoutedEvent == UIElement.MouseEnterEvent 
                   || x.RoutedEvent == UIElement.MouseLeaveEvent).ToList()) 
    { 
     grid.Triggers.Remove(eventToUnsubscribe); 
    }; 
Verwandte Themen