2012-08-29 48 views
5

Por ejemplo, yo podría hacer algo como esto:En WPF, ¿hay alguna forma de crear un StackPanel con columnas alineadas como una cuadrícula?

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*" /> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition Width="Auto" /> 
    </Grid.ColumnDefinitions> 
    <Grid.RowDefinitions> 
     <RowDefinition Width="Auto"> 
     <RowDefinition Width="Auto"> 
     <RowDefinition Width="Auto"> 
    </Grid.RowDefinitions> 
    <TextBlock Grid.Row="0" Grid.Column="0">Header 1</TextBlock> 
    <TextBox Grid.Row="0" Grid.Column="1" MaxLines="1" /> 
    <Button Grid.Row="0" Grid.Column="2">Send</Button> 
    <Button Grid.Row="0" Grid.Column="3">Save</Button> 
    <TextBlock Grid.Row="1" Grid.Column="0">Header 2</TextBlock> 
    <TextBox Grid.Row="1" Grid.Column="1" MaxLines="1" /> 
    <Button Grid.Row="1" Grid.Column="2">Send</Button> 
    <Button Grid.Row="1" Grid.Column="3">Save</Button> 
    <TextBlock Grid.Row="2" Grid.Column="0">Header 3</TextBlock> 
    <TextBox Grid.Row="2" Grid.Column="1" MaxLines="1" /> 
    <Button Grid.Row="2" Grid.Column="2">Send</Button> 
    <Button Grid.Row="2" Grid.Column="3">Save</Button> 
</Grid> 

o podría hacer algo como esto:

<StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock>Header 1</TextBlock> 
     <TextBox MaxLines="1" /> 
     <Button>Send</Button> 
     <Button>Save</Button> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock>Header 2</TextBlock> 
     <TextBox MaxLines="1" /> 
     <Button>Send</Button> 
     <Button>Save</Button> 
    </StackPanel> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock>Header 3</TextBlock> 
     <TextBox MaxLines="1" /> 
     <Button>Send</Button> 
     <Button>Save</Button> 
    </StackPanel> 
<StackPanel> 

Excepto que yo quiero ser capaz de manipular fácilmente las filas (añadir nuevas filas, mover las filas, etc.) como en el StackPanel, manteniendo las columnas alineadas correctamente como en la Grilla.

Respuesta

3

Puede usar muchas filas Grids con size sharing en las columnas. Se vuelve detallado cuando se realiza sin ningún control, por lo que podría encapsular cierta lógica (como crear columnas y asignar Grid.Column) en una derivada de ItemsControl o attached property por ejemplo.

4

Aquí hay una clase que acabo de lanzar para aproximadamente el mismo propósito: esencialmente, quería poder poner un montón de etiquetas en la columna izquierda y valores de diferentes tipos (cuadro de texto, menú desplegable, etc.) a la derecha.

Solo tiene dos columnas, pero podría adaptarse a diferentes números.

public class LabelValueGrid : Grid 
{ 
    public LabelValueGrid() 
     : base() 
    { 
     ColumnDefinitions.Add(new ColumnDefinition()); 
     ColumnDefinitions.Add(new ColumnDefinition()); 
     ColumnDefinitions[0].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto); 
     ColumnDefinitions[1].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star); 
    } 

    protected override void OnVisualChildrenChanged(System.Windows.DependencyObject visualAdded, System.Windows.DependencyObject visualRemoved) 
    { 
     base.OnVisualChildrenChanged(visualAdded, visualRemoved); 

     int curRow = -1; 
     int curCol = 1; 

     RowDefinitions.Clear(); 

     if (Children != null) 
      foreach (System.Windows.UIElement curChild in Children) 
      { 
       if (curCol == 0) 
        curCol = 1; 
       else 
       { 
        curCol = 0; 
        curRow++; 
        RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto)}); 
       } 

       Grid.SetRow(curChild, curRow); 
       Grid.SetColumn(curChild, curCol); 
      } 

     RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star)}); 
    } 
} 

puedo usar esto como una rejilla, excepto que acabo de enumerar los controles y luego se alternan las columnas automáticamente:

<local:LabelValueGrid> 
    <TextBlock Text="Label1"/> 
    <TextBox Name="value1"/> 
    <TextBlock Text="Label2"/> 
    <TextBox Name="value2"/> 
</local:LabelValueGrid> 
+0

Sólo por diversión, [Aquí hay una versión para UWP] (https://pastebin.com/2nstKFrC) basado en este código que parece funcionar bien. Sin embargo, no soy lo suficientemente inteligente como para haber encontrado el equivalente a 'OnVisualChildrenChanged' en UWP-land, por lo que es solo un método que llamas explícitamente y que contiene un 'IEnumerable '. – ruffin

Cuestiones relacionadas