1

I'm trying to make a budget program. Where I need to have groupboxes with a list of textblocks inside.

<ItemsControl DataContext="{Binding}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <GroupBox Header="{Binding}">
        <ItemsControl DataContext="{Binding}">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Text}" />
                <TextBlock Text="{Binding Value}" />
              </StackPanel>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </GroupBox>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

I need somehow to databind a list (perhaps?) with groupboxes so I'd create a list of group boxes, with some lines inside that would be a text with a currency value. So that I could create a group called "Apartment", with two lines "Rent $3000" and "Maintenance $150". Then I could have a second group called "Car" with lines "Insurance", "Loan" and "Maintenance" for instance.

But how would I databind this? And how would I need in C# to perform this. I'm at a loss.

1
  • 1
    Why don't you create a model that organizes your data more like what you are looking for, then create a template that you can more easily bind to? Commented Jun 22, 2011 at 19:34

2 Answers 2

6

Building off of Jay's comment, you would want to create a Hierarchical data model. Note I have left implementing INotifyPropertyChanged on the properties to you

public class BudgetLineItem : INotifyPropertyChanged
{
   public string Name { get; set; }
   public decimal Cost { get; set; }
}

public class BudgetGroup : INotifyPropertyChanged
{
   public string GroupName { get; set; }
   public ObservableCollection<BudgetLineItem> LineItems { get; set; }
}

public class BudgetViewModel : INotifyPropertyChanged
{
   public ObservableCollection<BudgetGroup> BudgetGroups { get; set; }
}

Then your data-template would look like this:

<ItemsControl DataContext="{Binding ViewModel}"
              ItemsSource="{Binding BudgetGroups}">
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <GroupBox Header="{Binding GroupName}">
        <ItemsControl ItemsSource="{Binding LineItems}">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Name}" />
                <TextBlock Text="{Binding Cost}" />
              </StackPanel>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
        </ItemsControl>
      </GroupBox>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
Sign up to request clarification or add additional context in comments.

Comments

0

I could be off base here, but it sounds like you want to change the DataTemplate based on the type of object that is being bound from a list of heterogeneous objects.

If that's the case, you want to look into DataTemplateSelectors or create DataTemplates for each of the types you want to support in the list.

For example, for an Apartment you might have:

<DataTemplate DataType="local:ApartmentBudget">
  <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Text}" />
    <TextBlock Text="{Binding Value}" />
  </StackPanel>
</DataTemplate>

a Car may look like:

<DataTemplate DataType="local:CarBudget">
  <StackPanel Orientation="Horizontal">
    <TextBlock Text="{Binding Insurance}" />
    <TextBlock Text="{Binding Loan}" />
    <TextBlock Text="{Binding Maintenance}" />
  </StackPanel>
</DataTemplate>

Then your ItemsControl can be set like:

<ItemsControl ItemSource="{Binding BudgetItems}">

The correct DataTemplate will be picked based on the data type. You can have even more control by creating a custom DataTemplateSelector.

See https://msdn.microsoft.com/en-us/library/ms742521(v=vs.100).aspx for more information.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.