WPF4Beginners: verrückte Wege für das Layout gleichgroßer Elemente

Es gibt 50 Wege die Freundin (den Freund) zu verlassen und etliche davon führen nach Rom. In einer Kaffeepause haben wir gegrübelt, wieviele Möglichkeiten es geben mag, gleichgroße Elemente in einem WPF Fenster unterzubringen. Hier sind die ersten Methoden. Für die gleichgroßen Elemente verwende ich in den Beispielen Buttons. Die Nachahmung ist nur bedingt zu empfehlen ;-)

Gridlayout

Über das Layout mit einem Grid kann die Größe durch die ColumnDefinitions und RowDefinitions festgelegt werden. Die Elemente werden durch die Zuordnung zu Spalten und Reihen in der Größe definiert. Will ich nun die Buttons verändern, muss ich die Spalten- und Reihendefinitionen verändern. Damit habe ich fast perfekt das Layout im Griff, allerdings immer noch mehr als eine Stelle, in welcher ich die Größe ändern muss.

<Grid x:Name="Sizer" >
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100" />
        <ColumnDefinition Width="10" />
        <ColumnDefinition Width="100" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="10" />
        <RowDefinition Height="30" />
    </Grid.RowDefinitions>
    <Button Grid.Column="0" Grid.Row="0"/>
    <Button Grid.Column="2" Grid.Row="0"/>
    <Button Grid.Column="0" Grid.Row="2"/>
    <Button Grid.Column="2" Grid.Row="2"/>
</Grid>

Das Ergebnis sieht so aus:

Layout per Style und Stackpanel

Das Stackpanel sortiert recht hübsch jeweils nach Vertikal oder Horizontal meine Elemente. Über Styles kann ich Werte eines Elementtypen festlegen. Dabei muss ich mich spezifischer dem Zieltypen (Tagettype) nähern, je typischer die zu beeinflussenden Eigenschaften (Properties) sind. Bei Höhe und Breite kann ich recht abstrakt bleiben und bin bei dem FrameworkElement noch gut aufgehoben.

<StackPanel >
    <StackPanel.Resources>
        <Style x:Key="Sizer" TargetType="FrameworkElement">
            <Setter Property="Width" Value="100"/>
            <Setter Property="Height" Value="30"/>
            <Setter Property="Margin" Value="0,0,10,10" />
        </Style>
    </StackPanel.Resources>
    <StackPanel Orientation="Horizontal">
        <Button Style="{StaticResource Sizer}"/>
        <Button Style="{StaticResource Sizer}"/>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <Button Style="{StaticResource Sizer}"/>
        <Button Style="{StaticResource Sizer}"/>
    </StackPanel>
</StackPanel>

Das sieht dann so aus. Der Nachteil wird dabei deutlich. Ich habe zwar nur eine Stelle, an der ich die Größe und die Abstände ändern muss, aber wenn ich später noch mehr Eigenschaften über Styles ändern will, muss ich sie kaskadieren oder mit BasedOn vererben und die Verwaltung und Organisiation von Styles in größeren Anwendungen ist ein Buchkapitel für sich.

Layout per DataBinding und WrapPanel

Das Wrappanel stapelt vorzugsweise horizontal und wenn das nicht klappt beginnt es eine neue Reihe. Die Breite, Höhe und Abstand der Elemente wird nun über ein Master-Element bestimmt, an dessen Properties die anderen Elemente sich orientieren. Die Orientierung erfolgt per Datenbindung. D.h. die gebundenen Eigenschaften des gebundenen Elements sind gleich der Eigenschaften des Masters.

<WrapPanel Width="220">
    <Button x:Name="Sizer" Width="100" Height="30" Margin="0,0,10,10" />
    <Button Width="{Binding ElementName=Sizer, Path=Width}" 
            Height="{Binding ElementName=Sizer, Path=Height}" 
            Margin="{Binding ElementName=Sizer, Path=Margin}" />
    <Button Width="{Binding ElementName=Sizer, Path=Width}" 
            Height="{Binding ElementName=Sizer, Path=Height}" 
            Margin="{Binding ElementName=Sizer, Path=Margin}" />
    <Button Width="{Binding ElementName=Sizer, Path=Width}" 
            Height="{Binding ElementName=Sizer, Path=Height}" 
            Margin="{Binding ElementName=Sizer, Path=Margin}" />
</WrapPanel>

Das ist mit Sicherheit die lustigste Art und Weise, gleichförmige Elemente zu erzeugen. Das Spannende daran ist, dass sie einiges an Vorteilen bietet: ich habe nur eine Stelle zum Ändern und alle nicht betroffenen Eigenschaften kann ich munter über Styles manipulieren. Der Nachteil (neben den schlecht lesbaren XAML Code) ist die kaum nachvollziehbare Struktur einer etwas komplexen Maske. Es gibt keine Darstellung, in welcher das Databindung erkennbar wäre.

Noch mehr Möglichkeiten?

Es sind uns noch andere Möglichkeiten eingefallen: von eigenen Controls (Custom, User), Templates in Itemlisten, ValueConverter für Größe und so weiter und so fort. Ob ich diese mal in einer ruhigen Minute aufzählen werde, weiß ich nicht. Die obigen Beispiele fand ich recht gut, um kurz und knackig mal die Layout Container, Styles und Databinding anzuschneiden. Wer Lust und Zeit hat, in dem eigenen Blog oder per Mail weitere verrrückte Wege für das Layout gleichgroßer Elemente aufzuzeigen, den verlinke ich hier gerne oder schreibe doch einfach einen Kommentar oder ein Trackback zu deinem Blog. Ich bin neugierig, ob sich jemand was wirklich schräges einfallen lässt.

Filed under: , ,

Comments

No Comments

Leave a Comment

(required) 
(required) 
(optional)
(required)