0

我想将我的数据模板绑定到 2 个数据源,一个数据源将实际定义列表框中的内容,另一个将确定列表框的数量以及列表框中的哪些项目被选中\选中。

我有以下 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;
        }
    }
}

它产生这个 在此处输入图像描述

我不想将 token1 或 token2 列表注入 DataEntity 对象,所以换句话说,我希望 DataEntity 构造函数成为

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

列表框数据模板应该选择

  • 如果 Dataentity.EntityTypeId = 1,tokens1 作为其 LisBoxItems 的数据源列出
  • tokens2 列表作为其 LisBoxItemsif DataEntity.EntityTypeId = 2 的数据源

此外,DataEntity 中的 TokenString 应绑定到列表框中的项目,即如果列表框显示 1 2 3 4 并且此列表框的 DataEntity 的 TokenString 值设置为“1,2,3”,则应在列表框中选中 1 2 3 在此处输入图像描述

4

2 回答 2

0

You're not thinking about this correctly. You need to create one class (some may call a view model) with the responsibility of providing all of the data that the view (or UI) will need. Therefore, you will need to have one property which holds a collection of type DataEntity (if I understand you correctly) to 'define what is in the outer ListBox' as you say.

Then you need a DataTemplate to describe what should be displayed for each item in the ListBox - your 'ItemTemplate' template. This DataTemplate should have another ListBox inside in which to display your Token objects. Your DataEntity should have something like this property in it:

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

You will then need another DataTemplate for your Token objects - your 'TokenListTemplate' template, but without the StackPanel... the inner ListBox replaces that, eg. if there are two Token objects in one DataEntity object, then that object would show two Checkboxes... you have correctly bound the IsChecked property to the Token.IsSelected property.

This may be complicated, but it is entirely possible. Just start with the first layer and get your DataEntity objects displayed in the outer ListBox using your 'ItemTemplate' template. Once that bit is ok, move on to the inner ListBox. Good luck.

于 2013-08-08T13:32:32.300 回答
0

我建议创建一个 ViewModel 作为模型和视图之间的层。在 ViewModel 中,您可以在不更改模型的情况下安排数据以适合使用的控件。

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

只需 Google for MVVM (Model-View-ViewModel) 获取示例和进一步解释,或查看此处的 SO(如MVVM:从头到尾的教程?)。

于 2013-08-08T13:28:57.037 回答