使用 WPF 和 C# 进行嵌套数据绑定

发布于 2024-11-16 14:41:37 字数 970 浏览 1 评论 0原文

我正在尝试制定一个预算计划。我需要有一个带有文本块列表的组框。

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

我需要以某种方式将列表(也许?)与组框进行数据绑定,以便我创建一个组框列表,其中的一些行将是具有货币值的文本。这样我就可以创建一个名为“公寓”的组,其中包含两行“租金 3000 美元”和“维护费用 150 美元”。然后我可以有第二个组,称为“汽车”,其中包含“保险”、“贷款”和“维护”行。

但我该如何对此进行数据绑定呢?我需要如何在 C# 中执行此操作。我不知所措。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风追烟花雨 2024-11-23 14:41:37

根据 Jay 的评论,您可能希望创建一个分层数据模型。注意我已将属性上的 INotifyPropertyChanged 实现留给了您

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

,那么您的数据模板将如下所示:

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

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>
别忘他 2024-11-23 14:41:37

我可能在这里偏离了基础,但听起来您想根据从异构对象列表绑定的对象类型来更改 DataTemplate。

如果是这种情况,您需要查看 DataTemplateSelectors 或为列表中要支持的每种类型创建 DataTemplate。

例如,对于公寓,您可能有:

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

汽车可能如下所示:

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

然后您的 ItemsControl 可以设置为:

<ItemsControl ItemSource="{Binding BudgetItems}">

将根据数据类型选择正确的 DataTemplate。您可以通过创建自定义 DataTemplateSelector 获得更多控制。

请参阅 https://msdn.microsoft.com/en -us/library/ms742521(v=vs.100).aspx 了解更多信息。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文