WPF - 将字符串列表绑定到ListBox的绑定类

时间:2015-06-29 17:17:51

标签: c# wpf xaml listbox

我将多个列表绑定到ListBox时遇到问题。我希望每个List都有不同的DataTemplate,颜色不同。

我有以下模型类

public class Users
{
        public Members Members{ get; set; }
}

public class Members
{
        public List<string> Moderators { get; set; }
        public List<string> Viewers { get; set; }
}

我使用INotifyPropertyChanged跟随ViewModel

private Users users;

public Users Users
{
    get { return users; }
    set
    {
        users= value;
        RaisePropertyChanged("Users");
    }
}

我绑定到此ListBox

<ListBox ItemsSource="{Binding Users.Members.Viewers}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
 </ListBox>

现在我只有一个List绑定到ListBox。它工作得很好,但我希望其他列表也绑定到同一个ListBox。除此之外,我希望版主拥有不同的模板。

我尝试了许多不同的东西,但似乎没有任何效果。

2 个答案:

答案 0 :(得分:2)

  1. 要合并两个列表并将其设置为ItemsSource,请使用 CompositeCollection
  2. WPF可以使用 ItemTemplateSelector 设置不同的模板,但它需要以某种方式使类不同。你的类型是字符串,所以它没有任何不同。我的提示是按如下方式创建枚举

    枚举MemberType     {         主持人,         查看器     }


  3. 以下课程:

    class Person
    {
        public string Name{get;set;}
        public MemberType Type{get;set;}
    }
    

    然后改为

    public class Members
        {
            public List<Person> Moderators { get; set; }
            public List<Person> Viewers { get; set; }
        }
    

    并最终在 ItemTemplateSelector

      public class TemplateSelector : DataTemplateSelector
        {
            public DataTemplate ViewerDataTemplate;
            public DataTemplate ModeratorDataTemplate;
    
            public override DataTemplate SelectTemplate(object item, DependencyObject container)
            {
                var member = item as Person;
                switch (member.Type)
                {
                    case MemberType.Moderator:
                        return ModeratorDataTemplate;
                    case MemberType.Viewer:
                        return ViewerDataTemplate;
                }
    
                return null;
            }
        }
    

答案 1 :(得分:2)

不是从原始对象中删除名称,而是为什么不保留它并根据原始类指定不同的颜色?

  

除此之外,我希望主持人拥有不同的模板。

如果你只有不可能的字符串。请记住,列表框最终只能看到一个列表;所以在一个列表中,如何将标记字符串作为主持人或查看者?

  

具有不同颜色的不同DataTemplate。

如果只有字符串,我建议您创建包装类,一个用于主持人,一个用于查看者,然后将字符串投影到要保留的类中。然后你可以按照我的建议/示例进行操作。

通过使用Composite集合来保存不同的项目(或者一个实际上可以使用基类列表或接口列表,如果实例具有该通用性),然后使用专门的数据模板对于原始类,可以这样做。

实施例

我有两个名为Ships的班级,一个名为Passage的班级。请注意,这两个类都具有Name属性,但是可以在模板中使用除Name之外的其他内容。

下面我定义数据模板和我的列表框。

<Grid>
    <Grid.Resources>
        <DataTemplate DataType="{x:Type c:Ship}">
            <TextBlock Text="{Binding Path=Name}"
                        Foreground="Red" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type c:Passage}">
            <TextBlock Text="{Binding Path=Name}"
                        Foreground="Blue" />
        </DataTemplate>
    </Grid.Resources>
    <ListBox Name="myListBox"
                Height="300"
                Width="200"
                ItemsSource="{Binding MyCompositeCollection}">
    </ListBox>
</Grid>

所以会发生什么事情,我的船将是红色的,通道将是蓝色的。 enter image description here

这是我在VM中的代码:

private CompositeCollection _MyCompositeCollection;

public CompositeCollection MyCompositeCollection
{
    get { return _MyCompositeCollection; }
    set { _MyCompositeCollection = value; OnPropertyChanged("MyCompositeCollection"); }
}

这里我加载了复合集合:

var temp  = new CompositeCollection();

Ships.ForEach(sh => temp.Add(sh));
Passages.ForEach(ps => temp.Add(ps));

MyCompositeCollection = temp;