Reputation: 5478
I need to create a dynamic UI in WPF. Something like below,
Date Hyatt Regency Ritz Carlton Holiday Inn..
16 10 5
12/16 20% 12% 10%
10 5 4
12/17 2% 3% 1%
Now, my question is that as the entire UI is dynamic, the hotel names the numeric amount, I am not able to space them properly. So if the hotel name becomes long the records below do not align properly. Is there a way in WPF that I can create the XAML from code behind dynamically and still look perfect spacing wise.
Upvotes: 0
Views: 198
Reputation: 7423
I think you are after something like this:
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
List<List<String>> data = GetData();
var grid = CreateGrid(data.Count, data.First().Count());
PopulateGrid( grid, data );
this.Content = grid;
}
private void PopulateGrid(Grid grid, List<List<string>> data)
{
int rowNumber = 0;
foreach (var rowContents in data)
{
int colNumber = 0;
foreach (var colValue in rowContents)
{
var tb = new TextBlock { Text = colValue, HorizontalAlignment = HorizontalAlignment.Center, Margin=new Thickness(5) };
Grid.SetRow(tb, rowNumber);
Grid.SetColumn(tb, colNumber);
grid.Children.Add(tb);
colNumber++;
}
rowNumber++;
}
}
private List<List<string>> GetData()
{
return new List<List<String>>()
{
new List<String>( ) { "Date", "Hyatt Regency", "Ritz Carlton", "Holiday Inn" },
new List<String>( ) { "", "16", "10", "5" },
new List<String>( ) { "12/16", "20%", "12%", "10%" },
new List<String>( ) { "", "", "", "" },
new List<String>( ) { "", "10", "5", "4" },
new List<String>( ) { "12/17", "2%", "3%", "1%" },
};
}
private Grid CreateGrid(int rows, int cols)
{
var grid = new Grid();
for (int r = 0; r < rows; r++)
grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
for (int c = 0; c < rows; c++)
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
return grid;
}
}
Upvotes: 1
Reputation: 96722
You can just use a regular old Grid
:
Date
Hyatt Regency
Ritz-Carleton
Holiday Inn
<TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">16</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="2" HorizontalAlignment="Right">10</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="3" HorizontalAlignment="Right">5</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center">12/16</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="1" HorizontalAlignment="Right">20%</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="2" HorizontalAlignment="Right">12%</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="3" HorizontalAlignment="Right">10%</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="1" HorizontalAlignment="Right">10</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="2" HorizontalAlignment="Right">5</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="3" HorizontalAlignment="Right">4</TextBlock>
<TextBlock Grid.Row="4" Grid.Column="0" HorizontalAlignment="Center">12/17</TextBlock>
<TextBlock Grid.Row="4" Grid.Column="1" HorizontalAlignment="Right">2%</TextBlock>
<TextBlock Grid.Row="4" Grid.Column="2" HorizontalAlignment="Right">3%</TextBlock>
<TextBlock Grid.Row="4" Grid.Column="3" HorizontalAlignment="Right">1%</TextBlock>
</Grid>
<TextBlock/>
</DockPanel>
But if you're building something like this using code-behind, you're doing it wrong. You should be using data templates and binding. To do this, you'd actually create a separate grid for each block of data, and use shared size groups to keep the column widths in sync. That's a somewhat bigger question, but one that you can address after you've got the layout right.
Upvotes: 0
Reputation: 17272
Did you try DataGrid?
If the inbuilt one doesn't do it for you, there are plenty of third party data grid controls:
And many more. If you look around, you can find free ones as well.
Upvotes: 1