2013-04-08 10 views
13

Ich arbeite an wpf Fenster, das mit der Verpackung neben einander Liste der Elemente zeigen, habe ich versucht, WrapPanel auf diese Weise zu verwenden:Feste Wrap Panel wpf

<Grid> 
    <ItemsControl> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel Orientation="Horizontal"/> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 

     <ItemsControl.Items> 
      <Button Content="01" Height="30" Width="70"/> 
      <Button Content="02" Height="35" Width="72"/> 
      <Button Content="03" Height="20" Width="74"/> 
      <Button Content="04" Height="25" Width="76"/> 
      <Button Content="05" Height="18" Width="78"/> 
      <Button Content="06" Height="50" Width="70"/> 
      <Button Content="07" Height="40" Width="72"/> 
      <Button Content="08" Height="55" Width="74"/> 
      <Button Content="09" Height="45" Width="76"/> 
      <Button Content="10" Height="25" Width="78"/> 
      <Button Content="11" Height="20" Width="80"/> 
      <Button Content="12" Height="30" Width="70"/> 
      <Button Content="13" Height="45" Width="72"/> 
      <Button Content="14" Height="30" Width="74"/> 
      <Button Content="15" Height="20" Width="76"/> 
      <Button Content="16" Height="25" Width="78"/> 
      <Button Content="17" Height="35" Width="80"/> 
      <Button Content="18" Height="50" Width="70"/> 
      <Button Content="19" Height="55" Width="72"/> 
      <Button Content="20" Height="45" Width="74"/> 
      <Button Content="21" Height="20" Width="76"/> 
      <Button Content="22" Height="60" Width="78"/> 
      <Button Content="23" Height="20" Width="80"/> 
      <Button Content="24" Height="25" Width="70"/> 
      <Button Content="25" Height="30" Width="72"/> 
     </ItemsControl.Items> 
    </ItemsControl> 
</Grid> 

und das ist das Ergebnis:

enter image description here

Eigentlich ist das Ergebnis unbefriedigend für mich, denn wenn man die WrapPanel als Gitter (Zeilen und Spalten) vorstellt, werden Sie feststellen, dass es keine Spalten sind, aber es gibt feste Größe Reihen. Ich brauche zu WarpPanel oder eine gewisse Kontrolle auch ohne Spalten zu machen, schauen Sie sich diese imaginäre Bild:

enter image description here

Hinweis, dass es keine Zeilen ist und keine Spalten. das möchte ich machen.

Hat jemand Ideen, um dieses Problem zu lösen?

+0

ich bin nicht in der Lage jedes Bild zu sehen .. – Bathineni

+2

Wie Clemens bereits schrieb, müssen Sie Ihre eigene Panel mit einer Art bin-Verpackung schreiben. [This] (http://www.codeproject.com/Articles/210979/Fast-optimizing-rectangle-packing-algorithm-for-bu) könnte ein guter Anfang sein. – dowhilefor

Antwort

9

Sie könnten Ihre eigene benutzerdefinierte Panel-Klasse schreiben. Es gibt einige Tutorials im Web, google einfach "wpf custom panel".

Es läuft darauf hinaus, die Methoden MeasureOverride und ArrangeOverride zu überschreiben.


UPDATE: Der folgende einfache benutzerdefinierte Panels mehr könnte oder weniger tun, was Sie wollen.

public class PackPanel : Panel 
{ 
    protected override Size MeasureOverride(Size availableSize) 
    { 
     foreach (UIElement child in InternalChildren) 
     { 
      child.Measure(availableSize); 
     } 

     var positions = new Point[InternalChildren.Count]; 
     var desiredHeight = ArrangeChildren(positions, availableSize.Width); 

     return new Size(availableSize.Width, desiredHeight); 
    } 

    protected override Size ArrangeOverride(Size finalSize) 
    { 
     var positions = new Point[InternalChildren.Count]; 
     ArrangeChildren(positions, finalSize.Width); 

     for (int i = 0; i < InternalChildren.Count; i++) 
     { 
      var child = InternalChildren[i]; 
      child.Arrange(new Rect(positions[i], child.DesiredSize)); 
     } 

     return finalSize; 
    } 

    private double ArrangeChildren(Point[] positions, double availableWidth) 
    { 
     var lastRowStartIndex = -1; 
     var lastRowEndIndex = 0; 
     var currentWidth = 0d; 
     var desiredHeight = 0d; 

     for (int childIndex = 0; childIndex < InternalChildren.Count; childIndex++) 
     { 
      var child = InternalChildren[childIndex]; 
      var x = 0d; 
      var y = 0d; 

      if (currentWidth == 0d || currentWidth + child.DesiredSize.Width <= availableWidth) 
      { 
       x = currentWidth; 
       currentWidth += child.DesiredSize.Width; 
      } 
      else 
      { 
       currentWidth = child.DesiredSize.Width; 
       lastRowStartIndex = lastRowEndIndex; 
       lastRowEndIndex = childIndex; 
      } 

      if (lastRowStartIndex >= 0) 
      { 
       int i = lastRowStartIndex; 

       while (i < lastRowEndIndex - 1 && positions[i + 1].X < x) 
       { 
        i++; 
       } 

       while (i < lastRowEndIndex && positions[i].X < x + child.DesiredSize.Width) 
       { 
        y = Math.Max(y, positions[i].Y + InternalChildren[i].DesiredSize.Height); 
        i++; 
       } 
      } 

      positions[childIndex] = new Point(x, y); 
      desiredHeight = Math.Max(desiredHeight, y + child.DesiredSize.Height); 
     } 

     return desiredHeight; 
    } 
} 
+0

Entschuldigung, aber es gibt Dutzende von Must-Check-Fällen, und die Check-Art ist sehr komplex :(Ist dies die einzige Möglichkeit, das gewünschte Panel zu machen? – MoHaKa

+0

Nicht sicher, was genau Sie mit "Must-Check Fällen", aber die Berechnung, die benötigt wird, um die Kindelemente anzuordnen, muss irgendwo gemacht werden.Wenn Sie keine vorhandene Panel Klasse mit dem gewünschten Verhalten finden können (und ich bezweifle, dass Sie das können), müssen Sie es selbst tun. – Clemens

+0

Siehe mein Update für eine mögliche Implementierung – Clemens

-1

Sie können entweder Leinwand verwenden:

oder verwenden Sie Grid und stellen Sie den Rand jeder Knöpfe nach requirenment

 <Canvas > 
     <Button Content="s" Width="50" Canvas.Left="17" Canvas.Top="20" /> 
     <Button Canvas.Left="73" Canvas.Top="32" Content="s" Width="60" Height="42" /> 
     <Button Canvas.Left="139" Canvas.Top="10" Content="s" Height="42" Width="60" /> 
    </Canvas> 

     <Grid > 
      <Button Content="01" Height="30" Width="70" Margin="20,12,414,268" /> 
      <Button Content="02" Height="35" Width="72" Margin="426,148,6,128" /> 
      <Button Content="03" Height="20" Width="74" Margin="190,122,240,170" /> 
      <Button Content="04" Height="25" Width="76" Margin="386,26,40,260" /> 
      <Button Content="05" Height="18" Width="78" Margin="376,202,48,92" /> 
      <Button Content="06" Height="50" Width="70" Margin="385,64,48,196" /> 
      <Button Content="07" Height="40" Width="72" Margin="162,202,269,68" /> 
      <Button Content="08" Height="55" Width="74" Margin="20,154,408,102" /> 
      <Button Content="09" Height="45" Width="76" Margin="21,95,406,171" /> 
      <Button Content="10" Height="25" Width="78" Margin="44,47,382,239" /> 
      <Button Content="11" Height="20" Width="80" Margin="386,120,38,170" /> 
      <Button Content="12" Height="30" Width="70" Margin="95,13,338,268" /> 
      <Button Content="13" Height="45" Width="72" Margin="290,6,140,260" /> 
      <Button Content="14" Height="30" Width="74" Margin="210,38,220,244" /> 
      <Button Content="15" Height="20" Width="76" Margin="128,48,299,242" /> 
      <Button Content="16" Height="25" Width="78" Margin="265,189,160,97" /> 
      <Button Content="17" Height="35" Width="80" Margin="176,154,246,122" /> 
      <Button Content="18" Height="50" Width="70" Margin="100,146,333,116" /> 
      <Button Content="19" Height="55" Width="72" Margin="270,121,160,135" /> 
      <Button Content="20" Height="45" Width="74" Margin="348,148,81,118" /> 
      <Button Content="21" Height="20" Width="76" Margin="94,78,332,212" /> 
      <Button Content="22" Height="60" Width="78" Margin="270,60,155,192" /> 
      <Button Content="23" Height="20" Width="80" Margin="176,74,247,216" /> 
      <Button Content="24" Height="25" Width="70" Margin="194,95,238,191" /> 
      <Button Content="25" Height="30" Width="72" Margin="117,104,314,177" /> 

    </Grid> 
Verwandte Themen