Domanda

Voglio semplicemente aprire il popup con un ritardo, un po 'come un descrizione comandi.

Come posso raggiungere questo obiettivo?

E, a proposito, Popup.PopupAnimation = PopupAnimation.Fade ... svanisce in troppo in fretta. Voglio almeno mezzo secondo in là.

È stato utile?

Soluzione 3

Prima di tutto ... il merito di questa risposta va a Eric Burke . Egli href="http://groups.google.com/group/wpf-disciples/browse_frm/thread/32f1131129d5bf00?tvc=1" risposto questa domanda ha scritto in WPF gruppo discepoli. Ho pensato che sarebbe stato utile per mettere questa risposta su StackOverflow troppo.

Fondamentalmente, è necessario animare la proprietà IsOpen del popup con un DiscreteBooleanKeyFrame.

Controlla la seguente XAML (che può essere facilmente incollato in Kaxaml o un'altra utilità di modifica XAML sciolti):

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
    <ContentPresenter>
        <ContentPresenter.ContentTemplate>
            <DataTemplate>
                <Grid>
                    <CheckBox
                        x:Name="cb"
                        Width="100"
                        Height="40"
                        Content="Hover Over Me"
                    />
                    <Popup
                        x:Name="popup"
                        Placement="Bottom"
                        PlacementTarget="{Binding ElementName=cb}"
                    >
                        <Border Width="400" Height="400" Background="Red"/>
                    </Popup>
                </Grid>
                <DataTemplate.Triggers>
                    <Trigger SourceName="cb" Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard x:Name="bsb">
                                <Storyboard>
                                    <BooleanAnimationUsingKeyFrames
                                        Storyboard.TargetName="popup"
                                        Storyboard.TargetProperty="IsOpen"
                                        FillBehavior="HoldEnd"
                                    >
                                        <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
                                     </BooleanAnimationUsingKeyFrames>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <StopStoryboard BeginStoryboardName="bsb"/>
                        </Trigger.ExitActions>
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ContentPresenter.ContentTemplate>
    </ContentPresenter>
</Page>

Si prega di notare che ho modificato la sua soluzione originale un po '... per attivare l'IsOpen al passaggio del mouse contro selezionando la casella come lui aveva. Il tutto nel tentativo di rendere Popup comportarsi un po 'come descrizione comandi.

Altri suggerimenti

È possibile creare uno stile da applicare alla comparsa nel seguente modo:

<Style x:Key="TooltipPopupStyle" TargetType="Popup">
    <Style.Triggers>
        <DataTrigger Binding="{Binding PlacementTarget.IsMouseOver, RelativeSource={RelativeSource Self}}" Value="True">
            <DataTrigger.EnterActions>
                <BeginStoryboard x:Name="OpenPopupStoryBoard" >
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:0.25" Value="True"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.EnterActions>
            <DataTrigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <BeginStoryboard x:Name="ClosePopupStoryBoard">
                    <Storyboard>
                        <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsOpen" FillBehavior="HoldEnd">
                            <DiscreteBooleanKeyFrame KeyTime="0:0:1" Value="False"/>
                        </BooleanAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </DataTrigger.ExitActions>
        </DataTrigger>

        <Trigger Property="IsMouseOver" Value="True">
            <Trigger.EnterActions>
                <PauseStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <PauseStoryboard BeginStoryboardName="OpenPopupStoryBoard"/>
                <ResumeStoryboard BeginStoryboardName="ClosePopupStoryBoard" />
            </Trigger.ExitActions>
        </Trigger>
    </Style.Triggers>
</Style>

Poi, ogni volta che si desidera utilizzarlo, si può scrivere markup simile a questo (notare l'associazione per la PlacementTarget):

<TextBlock x:Name="TargetControl" Text="Hover over me!" />
<Popup PlacementTarget="{Binding ElementName=TargetControl}" Style="{StaticResource TooltipPopupStyle}">
    <Border BorderBrush="Red" BorderThickness="1" Background="White">
        <TextBlock Text="This is a Popup behaving somewhat like the tooltip!" Margin="10" />
    </Border>
</Popup>

I cplotts risposta incollate è buona, ma potrebbero non essere applicabili nel tuo caso perché lascia l'animazione attaccato alla proprietà IsOpen, in modo efficace il blocco in posizione e impedendo che venga cambiato tramite impostazione diretta proprietà, vincolante, e altri modi. Questo può rendere difficile da utilizzare con il codice, a seconda di come lo si utilizza.

Se questo è il caso, vorrei passare a iniziare un DispatcherTimer quando si desidera aprire un pop-up con un certo ritardo, in questo modo:

_popupTimer = new DispatcherTimer(DispatcherPriority.Normal);
_popupTimer.Interval = TimeSpan.FromMilliseconds(100);
_popupTimer.Tick += (obj, e) =>
{
  _popup.IsOpen = true;
};
_popupTimer.Start();

Per un comportamento descrizione comandi simile a questo potrebbe essere fatto su MouseEnter. Se si desidera annullare l'apertura pop-up per qualche motivo (ad esempio, se il mouse lascia il controllo prima che appaia il pop-up), semplicemente:

_popupTimer.Stop();

Aggiorna

Come cplotts obseved nel commento, sarà anche necessario impostare _popup.IsOpen = false in alcune situazioni, in caso MouseLeave, a seconda della logica per la gestione il mouse entrare / eventi di uscita tra il controllo e il popup. Essere consapevoli del fatto che di solito non si vuole impostare ciecamente IsOpen=false su ogni evento MouseLeave, perché può farlo quando il pop-up appare su di esso. Ciò in alcune situazioni portare ad un popup sfarfallio. Quindi avrete bisogno di una logica c'è.

System.Windows.Controls.ToolTip tp = new System.Windows.Controls.ToolTip();

System.Windows.Threading.DispatcherTimer tooltipTimer =
    new System.Windows.Threading.DispatcherTimer
    (
        System.Windows.Threading.DispatcherPriority.Normal
    );

private void TooltipInvalidCharacter()
{
    tp.Content =
        "A flie name cannot contain any of the following character :" +
        "\n" + "\t" + "\\  / : *  ?  \"  <  >  |";

    tooltipTimer.Interval = TimeSpan.FromSeconds(5);
    tooltipTimer.Tick += new EventHandler(tooltipTimer_Tick);
    tp.IsOpen = true;
    tooltipTimer.Start();       
}

void tooltipTimer_Tick(object sender, EventArgs e)
{
     tp.IsOpen = false;
     tooltipTimer.Stop();
}

È possibile estendere il codice XAML per questa soluzione in modo che i soggiorni popup aperto fino a quando il mouse si trova sopra di esso, poi scompare automaticamente.

Ho modificato il campione come segue:

  1. Crea un'animazione "ClosePopop" che imposta IsOpen False dopo 0,5 secondi. Ho fatto questo una risorsa perché è utilizzato due volte.
  2. Per grilletto IsMouseOver del controllo, aggiungere un ExitAction che inizia l'animazione ClosePopup. Questo dà all'utente la possibilità di spostare il mouse sopra il pop-up prima che si chiuda. Ho chiamato questa animazione "BXB"
  3. Aggiungi un trigger alla proprietà IsMouseOver del pop-up. Al passaggio del mouse, fermarsi (ma non rimuovere) l'animazione originale "BXB" ClosePopup. Questo lascia la comparsa visibile; rimuovendo l'animazione qui farà la comparsa vicino.
  4. mouseout del popup, avviare una nuova animazione ClosePopup quindi rimuovere l'animazione "BXB". L'ultimo passo è fondamentale perché altrimenti la prima, l'animazione fermato "BXB" non mancherà di tenere il popup aperta.

Questa versione gira l'azzurro pop mentre il mouse è su di esso in modo da poter vedere la sequenza di eventi con Kaxaml .

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
 <DataTemplate x:Key="TooltipPopup">
  <Grid>
    <CheckBox
        x:Name="cb"
        Width="100"
        Height="40"
        Content="Hover Over Me"/>
    <Popup
        x:Name="popup"
        Placement="Bottom"
        PlacementTarget="{Binding ElementName=cb}">
        <Border x:Name="border" Width="400" Height="400" Background="Red"/>
    </Popup>
  </Grid>
  <DataTemplate.Resources>
    <Storyboard x:Key="ClosePopup">
        <BooleanAnimationUsingKeyFrames
                        Storyboard.TargetName="popup"
                        Storyboard.TargetProperty="IsOpen"
                        FillBehavior="Stop">
            <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="False"/>
        </BooleanAnimationUsingKeyFrames>
    </Storyboard>
  </DataTemplate.Resources>
  <DataTemplate.Triggers>
    <Trigger SourceName="cb" Property="IsMouseOver" Value="True">
        <Trigger.EnterActions>
            <BeginStoryboard x:Name="bsb" >
                <Storyboard>
                    <BooleanAnimationUsingKeyFrames
                        Storyboard.TargetName="popup"
                        Storyboard.TargetProperty="IsOpen"
                        FillBehavior="HoldEnd">
                        <DiscreteBooleanKeyFrame KeyTime="0:0:0.5" Value="True"/>
                    </BooleanAnimationUsingKeyFrames>
                </Storyboard>
            </BeginStoryboard>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <StopStoryboard BeginStoryboardName="bsb"/>
            <BeginStoryboard x:Name="bxb" Storyboard="{StaticResource ClosePopup}"/>
        </Trigger.ExitActions>
    </Trigger>
    <Trigger SourceName="popup" Property="IsMouseOver" Value="True">
        <Setter TargetName="border" Property="Background" Value="Blue"/>
        <Trigger.EnterActions>
            <StopStoryboard BeginStoryboardName="bxb"/>
        </Trigger.EnterActions>
        <Trigger.ExitActions>
            <BeginStoryboard Storyboard="{StaticResource ClosePopup}"/>
            <RemoveStoryboard BeginStoryboardName="bxb"/>
        </Trigger.ExitActions>
    </Trigger>
  </DataTemplate.Triggers>
 </DataTemplate>
</Page>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top