none
"Schiefes" Grid RRS feed

  • Frage

  • Hallo!

    Ist es möglich ein Grid, mit "schiefen" (nicht senkrechten [90°]) Spalten in einem Winkel von ca 70° zu erstellen?

    Fred



    • Bearbeitet perlfred Donnerstag, 6. April 2017 11:56
    Donnerstag, 6. April 2017 10:19

Antworten

  • Hi Fred,
    hier mal eine Demo, wie man das machen kann. Es muss lediglich das Grid mit Skew geneigt werden und der Inhalt in den Zellen mit Skew und dem analogen negativem Wert wieder zurück geneigt werden, damit es wieder "gerade" angezeigt wird.

    <Window x:Class="Window02"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window02" Height="300" Width="300">
      <Window.Resources>
        <Style TargetType="Label">
          <Setter Property="LayoutTransform">
            <Setter.Value>
              <SkewTransform AngleX="20"/>
            </Setter.Value>
          </Setter>
        </Style>
      </Window.Resources>
      <Grid>
        <Grid Height="200" Width="200">
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.LayoutTransform>
            <SkewTransform AngleX="-20"/>
          </Grid.LayoutTransform>
          <Border Grid.Row="0" Grid.Column="0" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 1"/>
          </Border>
          <Border Grid.Row="0" Grid.Column="1" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 2"/>
          </Border>
          <Border Grid.Row="1" Grid.Column="0" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 3"/>
          </Border>
          <Border Grid.Row="1" Grid.Column="1" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 4"/>
          </Border>
        </Grid>
      </Grid>
    </Window>


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort markiert perlfred Donnerstag, 13. April 2017 12:22
    Mittwoch, 12. April 2017 09:27
  • Hallo,

    was willst du denn genau erreichen? Einfach nur das Grid transformieren geht mit Hilfe einer SkewTransform. Das wird den Inhalt allerdings auch verzehren, wenn du dort nicht die umgekehrte Transformation anwendest. Von daher: Was hast du vor?


    Viele Grüße, Tom Lambert - MVP, MCC und MSP
    Wozu Antworten markieren und Posts bewerten? Klicke hier
    Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
    Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub

    • Als Antwort markiert perlfred Donnerstag, 13. April 2017 13:42
    Donnerstag, 6. April 2017 12:29
    Moderator

Alle Antworten

  • Hallo,

    was willst du denn genau erreichen? Einfach nur das Grid transformieren geht mit Hilfe einer SkewTransform. Das wird den Inhalt allerdings auch verzehren, wenn du dort nicht die umgekehrte Transformation anwendest. Von daher: Was hast du vor?


    Viele Grüße, Tom Lambert - MVP, MCC und MSP
    Wozu Antworten markieren und Posts bewerten? Klicke hier
    Nützliche Links: .NET Quellcode | C#/VB.NET Konverter | GitHub Forum Samples | Account bestätigen (Verify Your Account)
    Ich: Webseite | Facebook | Twitter | Code Snippets | GitHub

    • Als Antwort markiert perlfred Donnerstag, 13. April 2017 13:42
    Donnerstag, 6. April 2017 12:29
    Moderator
  • Hallo Palin!

    Danke für deine Antwort!

    Deine Lösung geht an meiner Vorstellung ein wenig vorbei. Die Transformation dreht (den Inhalt des) das Grid. Ich möchte aber "nur" die "Positionierung" der Framwork-Elemente im Grid an einem Raster, welches nicht senkrecht orientiert ist, erreichen.

    Ich weis, ich könnte durch Berechnung(en) und einem linken Margin auch meine Positionierung realisieren, doch gestaltet sich dies bei Größenänderungen des übergeordneten Objektes schon recht aufwändig.

    Hier ein Vergleich: (nur die Grid-Spalten sollten eben schräg sein :-))

         

    Donnerstag, 6. April 2017 12:37
  • Typischerweise dreht man in solchen Fällen den ViewPort.

    Ein paar Grundlagen dazu: 
    Viewports and content

    Und hier stellt jemand ein Beispiel dazu vor:

    http://blog.elentok.com/2011/03/wpf-pan-zoom-rotate-control.html


    - Gruß Florian


    • Bearbeitet Florian Haupt Donnerstag, 6. April 2017 13:11 Link ergänzt
    Donnerstag, 6. April 2017 12:54
  • Hallo Florian und Tom!

    Wie ich in meiner Antwort an Palin versucht habe zu erklären, möchte ich nicht! den Inhalt des Grid's drehen, verschieben, zoomen .... oder alles in Kombination.

    Ein Grid dient doch zur Positionierung (Verteilung) der in ihm enthaltenen Framwork-Objekte. 

    Ich hätte jetzt gern eine Matrix (= Grid), bei der die Spaltennicht senkrecht zu den Zeilen verlaufen, sondern in einem Winkel. Die Positionierung der Framwork-Elemente soll als Bezugspunkt die obere linke Ecke des Schnittpunktes zwischen Spalte und Zeile erhalten.

    Hintergrund dieses Wunsches ist ein UserControl, ähnlich dem einer Tastatur, bei dem  Framework-Objekte in einem Border in einer Schräge angeordnet werden sollen (viele Spalten). Bei Größenänderung des Borders sollen die Framework-Elemente äquivalent verschoben werden, aber eben immer in einer Schräge. Deshalb Grid mit schrägen Spalten.


    • Bearbeitet perlfred Donnerstag, 6. April 2017 14:45
    Donnerstag, 6. April 2017 14:16
  • Nun, ich habe nicht behauptet das Du alles drehen müsstest, perlfred.

    Es gibt keinen Grund deine am Grid orientierten Elemente zwingend der gleichen Koordinatentransformation zu unterwerfen.


    - Gruß Florian

    Donnerstag, 6. April 2017 14:29
  • Hallo Florian!

    Du hast schon recht, aber sobald ich das Grid drehe, werden mir auch die Zeilen mit gedreht. Es hat also keinen Sinn, die im Grid enthaltenen Framework-Objekte "zurück" zu drehen, die Position(en)! stimmen trotzdem nicht. (Zeilen sollen waagerecht bleiben.)

    Danke für deine Antwort!

    Fred.  

    Freitag, 7. April 2017 06:08
  • Hallo Florian!

    Du hast schon recht, aber sobald ich das Grid drehe, werden mir auch die Zeilen mit gedreht. Es hat also keinen Sinn, die im Grid enthaltenen Framework-Objekte "zurück" zu drehen, die Position(en)! stimmen trotzdem nicht. (Zeilen sollen waagerecht bleiben.)

    Danke für deine Antwort!

    Fred.  

    Hi,

    naja, das ist ja eigentlich ein zweistufiges Problem. Einerseits das gescherte Grid, andererseits die (Minimums)-Größe des in jeder Zelle enthaltenen Rechtecks zur Positionierung der Elemente.

    Du könntest also ein Control erstellen, welches Dir winkelabhängig eine "schräge" Zellenstruktur liefert mit Properties für das innere layout-rect für jede Zelle, die bestimmend für die äußere Größe der Gridzellen sind.

    Das bedeutet konkret:

    Wenn Du nur in x-richtung scherst, dann bestimmt die lineare Differenz der zwei (in x Richtung) nächstgelegenen Ecken des Parallelograms die maximale Größe des Rechtecks, das in die Zelle hineinpasst.

    Also, wenn Du scherst wie in Deinem Bild, dann wären das jeweils die Punkte 0 und 2 (wenn Du im Uhrzeigersinn pro Zelle durchnummerierst).

    Viele Grüße,

      Thorsten



    Freitag, 7. April 2017 09:18
  • <Grid Grid.Row="1"> <Grid.RenderTransform> <CompositeTransform SkewX="-45"/> </Grid.RenderTransform> <Grid Background="Black" Margin="0,0,-1134,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <StackPanel Background="#FFE8FF00"/> <StackPanel Grid.Column="2" Background="#FFE8FF00"/> <StackPanel Grid.Column="4" Background="#FFE8FF00"/> <StackPanel Grid.Column="6" Background="#FFE8FF00"/> <StackPanel Grid.Column="8" Background="#FFE8FF00"/> <StackPanel Grid.Column="10" Background="#FFE8FF00"/> <StackPanel Grid.Column="12" Background="#FFE8FF00"/> <StackPanel Grid.Column="14" Background="#FFE8FF00"/> </Grid> </Grid>
    Samstag, 8. April 2017 22:12
  • Hallo Marcus!

    Danke für deine Antwort.

    Deine Lösung neigt die im Grid  enthaltene Objekte, anstatt sie (unverändert!)  zu positionieren.

    Ein Grid positioniert (Matrix) die Objekte und verändert sie nicht!!! 

    Ich suche eine Lösung, die diese Positionierung eben schräg ausführen kann. (Siehe obige Abbildung.)

    Trotzdem nochmals danke für deine Unterstützung.

    Fred.

    Mittwoch, 12. April 2017 07:40
  • Hi Fred,
    hier mal eine Demo, wie man das machen kann. Es muss lediglich das Grid mit Skew geneigt werden und der Inhalt in den Zellen mit Skew und dem analogen negativem Wert wieder zurück geneigt werden, damit es wieder "gerade" angezeigt wird.

    <Window x:Class="Window02"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Window02" Height="300" Width="300">
      <Window.Resources>
        <Style TargetType="Label">
          <Setter Property="LayoutTransform">
            <Setter.Value>
              <SkewTransform AngleX="20"/>
            </Setter.Value>
          </Setter>
        </Style>
      </Window.Resources>
      <Grid>
        <Grid Height="200" Width="200">
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
          </Grid.ColumnDefinitions>
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.LayoutTransform>
            <SkewTransform AngleX="-20"/>
          </Grid.LayoutTransform>
          <Border Grid.Row="0" Grid.Column="0" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 1"/>
          </Border>
          <Border Grid.Row="0" Grid.Column="1" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 2"/>
          </Border>
          <Border Grid.Row="1" Grid.Column="0" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 3"/>
          </Border>
          <Border Grid.Row="1" Grid.Column="1" BorderBrush="Red" BorderThickness="2">
            <Label Content="Zelle 4"/>
          </Border>
        </Grid>
      </Grid>
    </Window>


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    • Als Antwort markiert perlfred Donnerstag, 13. April 2017 12:22
    Mittwoch, 12. April 2017 09:27
  • Hallo Thorsten!

    Deine Überlegungen sind natürlich erst einmal alle zutreffend!

    Sie beschreiben für meine Begriffe aber das weiterführende Problem, der Berechnung der X-Position einer einzelnen Zelle bei einer bestimmten Neigung und einer bestimmten Breite eines Framework-Objektes..

    Sehe ich das richtig?

    Wenn ich deine Überlegung fortführe, schlägst du also vor, ein Grid (das wiederum selbst ein UserControl sein müsste [SlopeControl]) mit UserControls (ZellControl) zu füllen, die die Positionierung der Framework-Objekte bei einem bestimmten Winkel übernehmen, zu erstellen?

    In etwa so:

    Das Problem ist, das ein Anschluss in der nächsten Zeile erfolgen sollte, deshalb geht es so auch nicht (ZellControls im Raster):

    Mittwoch, 12. April 2017 10:00
  • Hallo Thorsten!

    Deine Überlegungen sind natürlich erst einmal alle zutreffend!

    Sie beschreiben für meine Begriffe aber das weiterführende Problem, der Berechnung der X-Position einer einzelnen Zelle bei einer bestimmten Neigung und einer bestimmten Breite eines Framework-Objektes..


    Hi,

    ich meinte einfach die grundlegende Überlegung. Aus Mindestabstand und Tangens die Positionen errechnen.

    Wie Du das letzlich umsetzt ist, wie imer in WPF, auf mehreren Wegen möglich. Ich bin halt ein Freund des "Selberzeichnens", so würde ich ein UserControl erstellen, welches alles selbst macht, mit den vom Framework gelieferten Control-Primitives eventuell... aber Peter zeigt ja, dass es letzlich auch auf einfache Weise möglich ist.

    BTW: Welches Deiner Bilder zeigt denn, wie es sein sollte? Ich nehme an, das Untere?

    Viele Grüße,

      Thorsten

    Mittwoch, 12. April 2017 16:09
  • Hallo Peter!

    Da war ich wohl zu sehr im Problem gefangen und mehr auf eine inhaltliche als eine "optische" Lösung aus. (Zumal der erste Ansatz, alles zu drehen, funktional falsch war.) 

    Ich habe deine Lösung jetzt auch mit komplexen UserControls ausprobiert, sieht gut aus (keine Verzerrungen in Details usw.).
    Das ich für jeden Objekttyp, den ich im Grid benutze, eine (inverse) Skew-Transformation setzen muss, ist im Vergleich zu anderen Lösungen, immer noch das kleinste Problem.

    Vielen Dank! und allen ein schönes Osterfest!

        **  **
      **      **
     **       **                *** *
      **     **              **     ****
      **   **              *    **        **
        **   *            *   **    ***    **
          **   *        *   **           **  *
             ** **   ** **                 **
            **      **  **
         *                  *
       *                       *
      *     0            0      *
     *            @              *
      *                          *
         *         v          *

    Fred.

    Donnerstag, 13. April 2017 12:57
  • Hallo Tom!

    Ursprünglich dachte ich, dass man dieses Problem mit einem Control Template lösen könnte, deshalb wollte ich dir meine Vorstellungen erst einmal genauer darstellen ... (hatte mich aber Gedanklich festgefahren ...)

    Dein Ansatz ist mit dem von Peter identisch, ich hätte nur genauer lesen müssen :-(

    Danke für deine Antwort und auch dir ein frohes Fest!!!!

    Fred.

    Donnerstag, 13. April 2017 13:42