绑定到2个数据源

时间:2013-08-08 10:41:47

标签: wpf listbox datatemplate itemtemplate itemssource

我想将我的Datatemplate绑定到2个数据源,一个数据源将实际定义ListBox中的内容,而另一个数据源将确定那里有多少列表框以及列表框中的哪些项目被选中\检查。

我有以下XAML

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <DataTemplate x:Key="TokenListTemplate">
        <StackPanel Orientation="Horizontal">
            <CheckBox x:Name="chkToken" IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
                <TextBlock Text="{Binding Path=Text}" />
            </CheckBox>
        </StackPanel>
    </DataTemplate>

    <DataTemplate x:Key="ItemTemplate">
        <Border BorderThickness="1">
            <StackPanel Margin="3">
                <TextBlock Text="{Binding Path=Header}"/>
                <ListBox ItemTemplate="{StaticResource TokenListTemplate}" 
                         ItemsSource="{Binding Path=Tokens}" >
                </ListBox>
            </StackPanel>
        </Border>
    </DataTemplate>
</Window.Resources>

<Grid>
    <ListBox ItemTemplate="{StaticResource ItemTemplate}" 
             ItemsSource="{Binding}">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>
</Grid>

这就是代码隐藏

public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();

        ObservableCollection<DataEntity> _actualObjects;

        List<Token> tokens1 = new List<Token>() 
                                            { 
                                                new Token("1"),                                                     
                                                new Token("2"), 
                                                new Token("3"), 
                                                new Token("4") 
                                            };

        List<Token> tokens2 = new List<Token>() 
                                            { 
                                                new Token("11"),                                                     
                                                new Token("21"), 
                                                new Token("31")
                                            };

        _actualObjects = new ObservableCollection<DataEntity>()
            {
                new DataEntity(tokens1, "A", "1,2,3", 1),  
                new DataEntity(tokens1, "B", "2,3", 1),
                new DataEntity(tokens2, "C", "21,31", 2)
            };


        DataContext = _actualObjects;
    }

    class DataEntity
    {
        public DataEntity(List<Token> tokens, string header, string tokenString, int entityTypeId)
        {
            Tokens = tokens;
            Header = header;
            TokenString = tokenString;
            EntityTypeId = entityTypeId;
        }
        public List<Token> Tokens { get; set; }
        public String Header { get; set; }
        public String TokenString { get; set; }
        public int EntityTypeId { get; set; }

    }

    public class Token
    {
        public bool IsSelected { get; set; }
        public string Text { get; set; }
        public Token(string text)
        {
            this.IsSelected = false;
            this.Text = text;
        }
    }
}

它产生了这个 enter image description here

我不想将token1或token2 List注入DataEntity对象,换句话说我想要DataEntity构造函数

public DataEntity(string header, string tokenString, int entityTypeId)

Listbox DataTemplate应该选择

  • tokens1列出其LisBoxItems的数据源if Dataentity.EntityTypeId = 1
  • tokens2列出其LisBoxItemsif的数据源 DataEntity.EntityTypeId = 2

DataEntity中的TokenString也应绑定到列表框中的项目,即如果列表框显示1 2 3 4 此列表框的DataEntity将其TokenString值设置为“1,2,3”,然后在列表框中选中1 2 3 enter image description here

2 个答案:

答案 0 :(得分:0)

我建议将ViewModel创建为模型和视图之间的图层。在ViewModel中,您可以排列数据以适应所使用的控件,而无需更改模型。

因此,ViewModel可以将DataEntity的tokenString拆分为一个令牌列表。

Google for MVVM(Model-View-ViewModel)提供了示例和更详细的解释,或者在此处查看(例如MVVM: Tutorial from start to finish?)。

答案 1 :(得分:0)

你没有正确地思考这个问题。您需要创建一个类(有些可能称为视图模型),负责提供视图(或UI)所需的所有数据。因此,您需要拥有一个属性,其中包含DataEntity类型的集合(如果我理解正确的话),以“定义外部ListBox中的内容”。

然后您需要DataTemplate来描述ListBox - 您的'ItemTemplate'模板中每个项目应显示的内容。此DataTemplate内部应该有另一个ListBox,用于显示Token个对象。您的DataEntity应该包含类似此属性的内容:

public List<Token> Tokens 
{
    get 
    {
        if (EntityTypeId == 1) return tokens1;
        else if (EntityTypeId == 2) return tokens2;
    }
}

然后,您需要另外DataTemplateToken个对象 - 您的'TokenListTemplate'模板,但没有StackPanel ...内部ListBox会替换它,例如。如果一个Token对象中有两个DataEntity个对象,那么该对象将显示两个Checkbox es ...您已将IsChecked属性正确绑定到{{1}属性。

这可能很复杂,但完全有可能。只需从第一个图层开始,然后使用“ItemTemplate”模板将Token.IsSelected个对象显示在外部DataEntity中。一旦该位正常,请转到内部ListBox。祝你好运。