Announcement

Collapse
No announcement yet.

WPF: Fenster verschwinden lassen, wenn Maus es verlässt

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • WPF: Fenster verschwinden lassen, wenn Maus es verlässt

    Hallo,

    ich habe einen kleinen Dialog in ein Fenster gebaut, dass einfach verschwinden soll, sobald die Maus über dessen Grenzen zieht. Nur irgendwie kriege ich das nicht hin. Das XAML sieht in etwa so aus:
    [highlight=xml]
    <Window x:Class="winPrioPosition"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="winPrioPosition" Height="129" Width="248" ResizeMode="NoResize" WindowStyle="None">
    <Grid x:Name="gAssignmentDetails">
    <ContentControl x:Name="cAssignmentDetails" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Height="126" Width="245" BorderThickness="1" BorderBrush="Black">
    <Grid Background="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}">
    <Grid.Effect>
    <DropShadowEffect/>
    </Grid.Effect>
    ... diverse Controls
    </Grid>
    </ContentControl>
    </Grid>
    </Window>[/highlight]

    Das MouseLeave-Event ist dieses (ich habe eine Textbox in dem Dialog, befindet sich darin der Cursor, soll der Dialog natürlich nicht verschwinden):
    [highlight=vbnet]
    Private Sub cAssignmentDetails_MouseLeave(sender As Object, e As MouseEventArgs) Handles cAssignmentDetails.MouseLeave
    If Not txtTimeValueToAssign.IsFocused Then Me.Hide()
    End Sub[/highlight]

    Die ganze Sache funktioniert nur, wenn ich den Dialog über den unteren oder rechten Rand verlasse, quasi über den Schatten, mit dem ich das innere Grid versehen habe; verlasse ich nach oben oder links, wird das Fenster nicht ausgeblendet. Egal, ob ich das Ereignis nun an das Window oder das äußere Grid binde.

    Wie kriege ich das besser hin? Bin für jeden Tipp dankbar ...

    Dave

  • #2
    Hallo,

    ich würde das eher über EventTrigger lösen. Wenn dort die das MouseLeave-Ereignis auftritt, so z.B. die Visibility ändern.

    mfG Gü
    "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

    Comment


    • #3
      Hallo gfoidl,

      Danke schonmal für den Tipp, allerdings kriege ich es immer noch nicht hin. Ich weiß nicht genau, ob man dafür dann einen EventTrigger oder einen normalen Trigger nimmt. Ich habe jetzt folgendes probiert, das zumindest sauberes XAML zu sein scheint:[highlight=xml] <ContentControl x:Name="cAssignmentDetails" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Height="126" Width="245" BorderThickness="1" BorderBrush="Black">
      <ContentControl.Style>
      <Style TargetType="ContentControl">
      <Style.Triggers>
      <Trigger Property="IsMouseOver" Value="True">
      <Setter Property="Visibility" Value="hidden"/>
      </Trigger>
      </Style.Triggers>
      </Style>
      </ContentControl.Style>[/highlight]
      Aber dann flackert das Window nur wie wild, wenn ich die Maus darüber halte, egal ob ich sie bewege oder nicht. Ich bin auch nicht sicher, ob der Trigger bei dem ContentControl richtig aufgehoben ist oder nicht doch zum äußeren Grid als ... eben äußerstes Element gehört, nur da kriege ich das XAML nicht sauber hin.
      Ich habe relativ viel mit WinForms gemacht, daher hätte ich angenommen, dass man einen solchen Trigger dann direkt bei der Windows-Instanz implementiert, aber ich wüßte nicht wie.

      Was ich auch probiert habe, ist folgendes[highlight=xml] <Grid x:Name="gAssignmentDetails">
      <Grid.Triggers>
      <EventTrigger RoutedEvent="MouseLeave">
      <BeginStoryboard>
      <Storyboard>
      <!--<??? Property="Visibility" Value="Hidden">-->
      </Storyboard>
      </BeginStoryboard>
      </EventTrigger>
      <Grid.Triggers>[/highlight]aber da weiß ich nicht, wie man dann das gesamte Window anspricht, um es auszublenden ...

      Wäre toll, wenn mir hier noch jemand helfen könnte ... Danke schonmal vorab ...

      Dave

      Comment


      • #4
        Hallo,

        einfaches Beispiel. Angenommen es wird Window1 angzeigt (per Show-Methode) und wenn die Maus Window1 verlässt, so soll es nicht mehr angezeigt werden.

        [highlight=xml]
        <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Class="WpfApplication1.Window1"
        x:Name="Window"
        Title="Window1"
        Width="300" Height="250">

        <Window.Resources>
        <Storyboard x:Key="OnMouseLeave1">
        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="Window">
        <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
        </ObjectAnimationUsingKeyFrames>
        </Storyboard>
        </Window.Resources>

        <Window.Triggers>
        <EventTrigger RoutedEvent="Mouse.MouseLeave">
        <BeginStoryboard Storyboard="{StaticResource OnMouseLeave1}"/>
        </EventTrigger>
        </Window.Triggers>

        <Grid x:Name="LayoutRoot" Background="#FFD26D6D"/>
        </Window>
        [/highlight]

        Da so Window1 aber nicht aus dem Speicher entfernt wird, sollte die Referenz darauf gehalten werden und falls es wieder eingeblendet werden soll diese Instanz verwenden. Sonst könnte es zu einem Speicherleck kommen.

        mfG Gü
        "Any fool can write code that a computer can understand. Good programmers write code that humans can understand". - Martin Fowler

        Comment


        • #5
          Hallo gfoidl,

          nochmal vielen Dank ... aber es funktioniert leider nicht. Das heißt, nicht besser als zuvor. Verlasse ich das Fenster NICHT über den Schatten des inneren Grids, bleibt es ungerührt sichtbar. Nur mit einem Schwenk über den Schatten unten und rechts verschwindet das Fenster. Rufe ich es dann erneut auf:[highlight=vbnet] Dim _winPrioPosition As New winPrioPosition()

          Private Sub TextBlock_MouseEnter(sender As Object, e As MouseEventArgs)
          _winPrioPosition.SetPosition(lblDelegierenAn.Point ToScreen(Mouse.GetPosition(lblDelegierenAn)))
          _winPrioPosition.ShowDialog()
          End Sub[/highlight]bekomme ich nur ein schwarzes Viereck zu sehen, weil das Fenster noch auf hidden steht. Setze ich vor Aufruf des ShowDialogs noch ein _winPrioPosition.Visibility = Windows.Visibility.Visible ein, ändert das gar nichts; lt. Debugger bleibt die Eigenschaft auf "hidden" stehen.

          PS: Habe mal einen Screenshot von dem Dialog gemacht, vielleicht ist es ja nützlich zu sehen, wie ich es mir vorstelle:Unbenannt.png

          Comment


          • #6
            Durch Zufall und ewiges Rumprobieren habe ich nun rausbekommen, wie es funktioniert. Und zwar, mal wieder ganz einfach.Das XAML:[highlight=xml]<Window x:Name="window" x:Class="winPrioPosition"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="winPrioPosition" Height="129" Width="248" ResizeMode="NoResize" WindowStyle="None" MouseLeave="Window_MouseLeave">[/highlight]Und im Ereignis selbst ein simples Me.Hide().

            Und ich habe keine Ahnung, weshalb das auf die anderen Arten nicht geklappt hat ...

            Danke dennoch, gfoidl, für Deine Bemühungen ... sehr.

            Dave

            Comment

            Working...
            X