Deaktivierte Buttons und Margin-Verhalten

06.05.08 - .NET, WPF
Beitrag von Norbert Eder
 Wer ein StackPanel mit Buttons á la Visual Studio Toolbox entwickelt, der möchte eventuell diese contextsensitiv anzeigen. Eine Variante ist, alle Elemente zu laden und je nach Bedarf aus- bzw. einzublenden.

Dies in einem Window nachgestellt, könnte in etwa wie folgt per XAML definiert sein:
<Window.Resources>
    <Style TargetType="Button">
        <Setter Property="SnapsToDevicePixels" Value="true"/>
        <Setter Property="OverridesDefaultStyle" Value="true"/>
        <Setter Property="MinHeight" Value="0"/>
        <Setter Property="MinWidth" Value="75"/>
        <Setter Property="Margin" Value="10"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border x:Name="Border" 
                            Background="Beige"  
                            CornerRadius="2" 
                            BorderThickness="1" 
                            BorderBrush="Brown">
                        <ContentPresenter 
                            Margin="2" 
                            HorizontalAlignment="Center" 
                            VerticalAlignment="Center" 
                            RecognizesAccessKey="True"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsVisible" Value="false">
                            <Setter Property="Height" Value="0"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<StackPanel>
    <Button x:Name="Button1" 
            Content="Button1"/>
    <Button x:Name="Button2" 
            Content="Button2"/>
    <Button x:Name="Button3" 
            Content="Button3"/>
    <Button x:Name="SetButton" 
            Content="Toggle Button1 Un/Visible" 
            Click="SetButton_Click" />
    <Button x:Name="CheckButton" 
            Content="Check Height" 
            Click="CheckButton_Click"/>
</StackPanel>

Und so sieht es aus:



Damit die Buttons nicht aneinander kleben, wurde ein entsprechender Margin gesetzt. Nun soll (in diesem Beispiel) ein bestimmter Button ausgeblendet werden. Dies wird mit Hilfe eines anderen Buttons erledigt:
private void SetButton_Click(object sender, RoutedEventArgs e)
{
    if (Button2.Visibility == Visibility.Visible)
        Button2.Visibility = Visibility.Hidden;
    else
        Button2.Visibility = Visibility.Visible;
}

Soweit auch noch keine Tragik.

Wird nun der Button ausgeblendet, dann erhält man folgendes Ergebnis:



Eigentlich nicht ganz das, was man sich erwartet. Es wurde zwar der Button ausgeblendet, aber der definierte Margin ist nach wie vor vorhanden. Meiner Meinung nach, sollte der Margin ebenfalls ausgeblendet werden, so er denn logisch zum Button gehört.

Zu beachten ist der Trigger auf IsVisible im ContentTemplate, der die Höhe des Buttons auf 0 setzt, damit nicht nur der Button ausgeblendet wird, sondern der Zwischenraum durch die restlichen Buttons aufgefüllt wird.

Damit auch der Margin ausgeblendet wird, muss dieser im Trigger explizit auf 0 gestellt werden:
<Trigger Property="IsVisible" Value="false">
    <Setter Property="Height" Value="0"/>
    <Setter Property="Margin" Value="0"/>
</Trigger>

Nun erhält man das gewünschte Ergebnis:



PS: Schelm, wer Böses denkt und ein WrapPanel empfiehlt. Ist auch hier dasselbe.

 


Alexander

08.05.08
 Ich bitte gleich einmal um Entschuldigung, falls ich die Problemstellung in diesem Beispiel nicht ganz verstanden haben sollte, aber ich stelle mir folgende Frage:

Ist es nicht genauso zielführend und wesentlich einfacher, anstatt diesen (ich nenne es einmal) "Workaround" mit MinHeight + Height + IsVisible, etc. zu machen einfach beim besagten

private void SetButton_Click(object sender, RoutedEventArgs e)
{
if (Button2.Visibility == Visibility.Visible)
Button2.Visibility = Visibility.Hidden;
else
Button2.Visibility = Visibility.Visible;
}

statt
Button2.Visibility = Visibility.Hidden;
eifach
Button2.Visibility = Visibility.Collapsed;

zu schreiben?

Hätte doch denselben Effekt bräuchte nur diese EINE Code-Zeile.

lg
lx

 


Norbert

23.05.08
 Danke. Hatte ich übersehen. Die einfachsten Dinge sind wohl immer am weitesten entfernt ...
 


Kommentar hinzufügen

Bitte das Formular ausfüllen, um Deinen Kommentar hinzuzufügen.









Spezial-Code einfügen: