13 votes

Le contrôle du popup se déplace avec le parent

J'espère que cet article sera rapide pour les experts WPF. Existe-t-il une solution XAML simple pour permettre à mon popup de se déplacer lorsque la fenêtre se déplace ou change de taille ? Le code est ci-dessous. Sinon, je peux toujours gérer un événement dans le code derrière.

<Grid>
    <Canvas>
        <Expander Header="details" HorizontalAlignment="Center" VerticalAlignment="Top" ExpandDirection="Down"
                  Expanded="Expander_Expanded" Panel.ZIndex="99" Collapsed="Expander_Collapsed" Name="expander">

                <Popup PopupAnimation="Slide" Name="popup" Width="200" Height="200" StaysOpen="True" AllowsTransparency="True" 
                       IsOpen="False" >
                <Grid Background="Cornsilk">
                    <Grid.BitmapEffect>
                        <DropShadowBitmapEffect/>
                    </Grid.BitmapEffect>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                   <TextBlock TextWrapping="Wrap" FontWeight="Bold">
                      Some example text
                   </TextBlock>
                </Grid>
            </Popup>

        </Expander>
    </Canvas>
</Grid>

24voto

MasterMastic Points 3868

C'est à peu près la réponse de Rick mais en code-behind, car je vois absolument aucune raison pour introduire une autre dépendance.

protected override void OnLocationChanged(EventArgs e)
{
    popup.HorizontalOffset += 1;
    popup.HorizontalOffset -= 1;
    base.OnLocationChanged(e);
}

Il suffit de faire un copier-coller dans le code-behind de votre fenêtre et de remplacer la balise popup avec celui de l'identifiant de votre instance popup.


Je la trouve bien meilleure, elle est plus succincte, elle n'utilise pas d'événements dont vous devrez vous désabonner ou faire fuir la mémoire.
Et pour le runtime de votre application, la surcharge aura de meilleures performances (rien de notable mais les irrationalistes de la micro-performance, comme votre serviteur, l'adoreront quand même).

5voto

Rick Sladkey Points 23389

Voici une solution utilisant :

Cet échantillon, uniquement composé de balises, consiste en une zone de texte et une fenêtre contextuelle. La fenêtre contextuelle s'ouvre lorsque la zone de texte est mise en évidence. La fenêtre contextuelle suit la fenêtre lorsqu'elle se déplace en s'accrochant à l'événement de changement d'emplacement de la fenêtre et en forçant la fenêtre contextuelle à se repositionner en conséquence.

<Grid>
    <StackPanel>
        <TextBox x:Name="textBox1" Width="200" Height="20"/>
        <Popup PlacementTarget="{Binding ElementName=textBox1}" IsOpen="{Binding IsKeyboardFocused, ElementName=textBox1, Mode=OneWay}">
            <TextBlock Background="White" Text="Sample Popup content."/>
            <p:Attached.Operations>
                <p:EventHandler Path="Loaded">
                    <p:ScriptHandler Path="@FindAncestor([Window], @AssociatedObject.PlacementTarget).LocationChanged">
                        @AssociatedObject.HorizontalOffset += 1;
                        @AssociatedObject.HorizontalOffset -= 1;
                    </p:ScriptHandler>
                </p:EventHandler>
            </p:Attached.Operations>
        </Popup>
    </StackPanel>
</Grid>

0voto

Pavlo Glazkov Points 12183

Malheureusement, il n'y a pas de solution rapide. Vous pouvez utiliser une astuce que j'ai décrite ici : Comment faire en sorte que la liste déroulante de WPF Combobox reste ouverte et placée ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X