developer
developer

Reputation: 5478

Help with WPF UI

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

Answers (3)

grantnz
grantnz

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

Robert Rossney
Robert Rossney

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

Matěj Z&#225;bsk&#253;
Matěj Z&#225;bsk&#253;

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:

Telerik GridView

DevExpress DXGrid

And many more. If you look around, you can find free ones as well.

Upvotes: 1

Related Questions