1

I'm fairly new to C# and WPF, but I started building an application which should have a function of listing Items with a few details. Currently it looks like

The data for these 'items' (one item is multiple labels enclosed in a border (at a later time I would like to add a picture as well)) is loaded in through a REST Service and I don't know how many items will be responded. Now I have the problem of not beeing able to create the labels statically within the xaml because of the variating number of items recieved.

My question here is, how can I create multiple labels (as well as a border and an image) programmatically, align them correctly in the window and address the labels to fill them with data?

Thanks a lot for your help!

Sinatr
  • 20,892
  • 15
  • 90
  • 319
gameX
  • 23
  • 1
  • 8
  • 2
    I think you're after using an [ItemsControl](https://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol%28v=vs.110%29.aspx).There's also a decent tutorial [here](http://www.wpf-tutorial.com/list-controls/itemscontrol/) which may help. I haven't answered because there's a lot of example uses of ItemsControl on SO. Hopefully this will just push you in the right direction. – Carl Reid Oct 08 '15 at 15:04
  • Can you show the Json response object from the REST service? You will need to use Reflection to create the controls. Aligning them correctly in the window and filling the labels with data will depend on the structure you are getting back from the service call. – Bobby Oct 08 '15 at 15:18
  • Thanks for your help Yoink, I think a ListBox (later on in the tutorial you linked too) or ItemsControl is similar to what I'm looking for! @Bobby A link to the API and a respone I'm using: [link](https://wiki.guildwars2.com/wiki/API:2/commerce/transactions) – gameX Oct 08 '15 at 15:30
  • I see. the number of labels won't be variable; the number of "border bound items" returned by the REST call will be variable. You won;'t need reflection then. I'll post an answer that may point you in the right direction. – Bobby Oct 08 '15 at 15:48
  • Yes, exactly! I could've worded that better, thanks! – gameX Oct 08 '15 at 15:57

2 Answers2

1

As you indicated in your comment, a ListBox will probably suit your purposes. The general idea is that you want to specify the format of the ListBox via an ItemTemplate, and in the ItemTemplate specify a DataTemplate with the necessary controls to support your API data, with bindings specified to a model mapped from the JSON. An incomplete example of the XAML:

<ListBox x:Name="transactionsListBox">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border BorderBrush="Black" BorderThickness=".5" Padding="1">
                <StackPanel>
                    <Label x:Name="id" Content="{Binding Path=Id}" />
                    <Label x:Name="item_id" Content="{Binding Path=Item_Id}" />
                    <Label x:Name="price" Content="{Binding Path=Price}" />
                    <Label x:Name="quantity" Content="{Binding Path=Quantity}" />
                    <Label x:Name="created" Content="{Binding Path=Created}" />
                    <Label x:Name="purchased" Content="{Binding Path=Purchased}" />
                </StackPanel>
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

The Path= property of the bindings above need to match the property names of the model you create to store the transactions from your REST call. Then, when you have an instance of a list of that model type, your code would want to do something like:

List<Transaction> myTransactions = apiCall.response.mapToMyModel() // pseduocode
transactionsListBox.DataContext = myTransactions;
Bobby
  • 467
  • 4
  • 13
  • I left out the Image part of your request, but it is a simple extension of the controls defined in XAML as children of that StackPanel. – Bobby Oct 08 '15 at 16:08
  • Also, if you want finer control of the presentation of those labels, you may choose to use a Grid instead of a StackPanel, and customize the columns of the Grid to suit your presentation needs. – Bobby Oct 08 '15 at 16:10
  • `StackPanel` should have `Orientation="Horizontal"` too. – Carl Reid Oct 08 '15 at 16:16
  • 1
    Thanks a lot, works great (and thanks for the tipp with `Orientation="Horizontal"` ! However I have a further question, what is the difference between `tlb.DataContext` or `tlb.ItemsSource`, because in this case it only works with `tlb.ItemsSource` – gameX Oct 08 '15 at 16:30
  • `DataContext` is like saying "Here is the object type we will be dealing with" and `ItemsSource` is saying "Here is a list of things I wish to iterate over" – Carl Reid Oct 08 '15 at 16:50
1

To add to Bobby's answer, here's an example using an ItemsControl.

<ItemsControl ItemsSource="{Binding SellTransactions}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Grid.Column="0" Content="{Binding created}"></Label>
                <Label Grid.Column="1" Content="{Binding id}"></Label>
                <Label Grid.Column="2" Content="{Binding item_id}"></Label>
                <Label Grid.Column="3" Content="{Binding price}"></Label>
                <Label Grid.Column="4" Content="{Binding purchased}"></Label>
                <Label Grid.Column="5" Content="{Binding quantity}"></Label>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

The class for the transaction:

public class SellTransaction
{
    public long id { get; set; }
    public int item_id { get; set; }
    public int price { get; set; }
    public int quantity { get; set; }
    public DateTime created { get; set; }
    public DateTime purchased { get; set; }
}
Carl Reid
  • 771
  • 11
  • 23
  • Thanks a lot for your input! I'll use a Grid similar to the one you made inside a ListBox! :) – gameX Oct 08 '15 at 16:36