2012-08-29 20 views
5

Per esempio avrei potuto fare qualcosa di simile:In WPF, c'è un modo per creare uno StackPanel con colonne allineate come una griglia?

<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> 

Oppure avrei potuto fare qualcosa di simile:

<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> 

Solo che voglio essere in grado di manipolare facilmente le righe (aggiungere nuove righe, sposta le file in giro, ecc.) come nello StackPanel, mantenendo le colonne allineate correttamente come nella griglia.

risposta

3

È possibile utilizzare molte Grids su una riga con size sharing sulle colonne. Diventa prolisso quando viene eseguito senza alcun controllo, quindi è possibile incapsulare alcuni elementi logici (come la creazione di colonne e l'assegnazione di Grid.Column) in un derivato di ItemsControl o un attached property per esempio.

4

Ecco una classe che ho appena gettato insieme per circa lo stesso scopo: essenzialmente volevo essere in grado di mettere un mucchio di etichette nella colonna di sinistra e valori di diversi tipi (casella di testo, menu a discesa, ecc.) Sulla destra.

Ha solo due colonne, ma potrebbe essere adattato a numeri diversi.

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)}); 
    } 
} 

posso usare questo come una griglia, tranne ho solo elencare i controlli e poi si alterna le colonne automaticamente:

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

Solo per divertimento, [ecco una versione per UWP] (https://pastebin.com/2nstKFrC) basato su questo codice che sembra funzionare bene. Non sono abbastanza intelligente da aver trovato l'equivalente di "OnVisualChildrenChanged" in UWP-land, tuttavia, quindi è solo un metodo che chiamate esplicitamente, invece, che contiene un "IEnumerable ". – ruffin