来自DataTemplate的WPF数据绑定 - 多对多关系

时间:2014-07-24 11:44:04

标签: wpf many-to-many datatemplate

我有一个用于布置项目的WPF控件,并将ItemsSource设置为

ItemsSource="{Binding item_portfolio}" DataContext="{Binding SelectedItem}"

在布局控件的资源中,我为其项目设置了模板:

<Style>
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <StackPanel Orientation="Vertical" Margin="5">
                    <TextBlock Text="{Binding portfolio.PortfolioName}"  />
                    <ListView ItemsSource="{Binding ?}">
                    </ListView>
                </StackPanel>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

绑定的数据是多对多关系(一个项目可以有许多项目组合,一个项目组合可以有许多项目),并在数据库中的3个单独的表中指定(我使用实体框架来访问它)。下面的架构和示例数据:

item               item_portfolio                   portfolio
ID (PK)  Name      itemID (FK)  portfolioID (FK)    ID  PortfolioName
1        Item 1       1               1             1   Portfolio 1
2        Item 2       1               2             2   Portfolio 2
                      1               3             3   Portfolio 3
                      2               2
                      2               3                        
TextBlock下的

DataTemplate绑定正常工作。 但是,我不知道如何绑定ListView ItemsSource,以便显示属于该投资组合的所有项目对象。

编辑: 我想列出布​​局控件中的投资组合。然后在投资组合下,我想显示它包含的项目。下图显示了SelectedItem为Item 1时的UI。

enter image description here

(首先我展示了这个项目有哪些投资组合。这给出了3个投资组合。这样就行了。然后在UI上点击投资组合3,它应该显示属于该投资组合的所有项目(第1项和第2项)。还没有用。)

2 个答案:

答案 0 :(得分:0)

我们不会在代码中对数据模型进行建模,就像在数据库中建模一样。我们不会“加入课程”来模拟“加入表格”。相反,我们创建分层数据模型。在您的情况下,您应该拥有Item类,其Portfolio属性类型为Portfolio。应该没有ItemPortfolio类,因为它没有任何意义。然后,您的Binding应该是这个:

<ItemsControl ItemsSource="{Binding Items}" ... />

然后,您的DataTemplate(自动将DataContext设置为Item类集合中的项目)应该看起来更像这样:

<DataTemplate>
    <StackPanel Orientation="Vertical" Margin="5">
        <TextBlock Text="{Binding PortfolioName}" />
        <ListView ItemsSource="{Binding Portfolio}">
        </ListView>
    </StackPanel>
</DataTemplate>

显然,为了完成这项工作,您需要在Item课程中定义这些属性。


更新&gt;&gt;&gt;

在这种情况下,请创建一个Portfolio类,其Items属性为ObservableCollection<Item>,并设置ItemsSource,如下所示:

<ItemsControl ItemsSource="{Binding Item.Portfolios}" ... />

为了澄清,您的Item类还应该具有类型为ObservableCollection<Portfolio>的集合属性...此导致某些数据对象重复,但在WPF中它是更重要的是为您的观点提供所需的数据。

答案 1 :(得分:0)

我在这里使用 Expander control ,因为你想要PortfolioName作为标题并点击
 要显示对应的PortfolioItemList的PortfolioName。

xaml代码

<ItemsControl  MaxHeight="300" ItemsSource="{Binding PortfolioInfo}" ScrollViewer.VerticalScrollBarVisibility="Auto" >
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal"></StackPanel>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Expander>
                <Expander.Header>
                    <TextBlock Background="YellowGreen" Text="{Binding name}"></TextBlock>
                </Expander.Header>
                <Expander.Content>
                    <ListBox ItemsSource="{Binding ItemList}"></ListBox>
                </Expander.Content>
            </Expander>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

C#代码

public partial class MainWindow : Window
{
    public ObservableCollection<Portfolio> PortfolioInfo { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        PortfolioInfo = new ObservableCollection<Portfolio>()
        {
            new Portfolio(){name="Portfolio1", ItemList= new List<string>(){"Item1","Item2","Item3"}},
            new Portfolio(){name="Portfolio2", ItemList= new List<string>(){"Item1","Item2","Item3"}},
            new Portfolio(){name="Portfolio3", ItemList= new List<string>(){"Item1","Item2","Item3"}}                             
        };
        this.DataContext = this;
    }
}
public class Portfolio
{
    public string name { get; set; }
    public List<string> ItemList { get; set; }
}

注意:修改Expander样式/模板以获得所需的用户界面

<强> Rseult

enter image description here