【问题标题】:How to choose which ObservableCollection to bind to a listbox?如何选择绑定到列表框的 ObservableCollection?
【发布时间】:2012-05-25 11:11:39
【问题描述】:

这可能吗?我有两个 ObservableCollections。我想用其中一个绑定和填充一个列表框。例如,假设我们有 2 个按钮 - 一个用于 Twitter,一个用于 Facebook。单击 Facebook 按钮,它将使用来自 facebook 可观察集合的朋友姓名填充列表框,并将其绑定。单击 Twitter 它将用 Twitter 关注者填充列表框并填充列表框并绑定它。

如何选择要填充到列表框中的集合?

【问题讨论】:

    标签: c# wpf binding listbox observablecollection


    【解决方案1】:

    我只会使用一个可观察的集合并根据用户的选择进行填充。你也可以用两个来源的名字来填充它,并有一个过滤器来过滤掉一个或另一个(显然你需要一个包装器对象,你可以在其中指明这个名字是 Facebook 朋友还是 twitter 关注者)。

    编辑:下面是一些快速的代码示例,说明如何做到这一点:

    public interface ISocialContact
    {
        string Name { get; }
    }
    
    public class FacebookContact : ISocialContact
    {
        public string Name { get; set; }
        public string FacebookPage { get; set; }
    }
    
    public class TwitterContact : ISocialContact
    {
        public string Name { get; set; }
        public string TwitterAccount { get; set; }
    }
    

    然后在您的数据上下文中:

    public ObservableCollection<ISocialContact> Contacts { get; set; }
    
    ...
    
    Contacts = new ObservableCollection<ISocialContact> {
                        new FacebookContact { Name = "Face", FacebookPage = "book" },
                        new TwitterContact { Name = "Twit", TwitterAccount = "ter" } 
               };
    

    在你的 xaml 中:

    <Grid>
        <Grid.Resources>
            <DataTemplate DataType="{x:Type local:FacebookContact}">
                <TextBlock Text="{Binding FacebookPage}"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type local:TwitterContact}">
                <TextBlock Text="{Binding TwitterAccount}"/>
            </DataTemplate>
        </Grid.Resources>
        <ListBox ItemsSource="{Binding Contacts}" Width="100" Height="100"/>
    </Grid>
    

    这会将适当的模板应用于您集合中的每个对象。因此,您可以仅使用 facebook 联系人或仅使用 twitter 联系人或混合进行收藏。

    另请注意:您不需要通用接口。如果您只是将ObservableCollection 设为object 类型,它也将起作用。但是鉴于它们是由同一个应用程序在同一个列表框中显示的,这表明您可以找到某种通用基础,并且可以创建通用接口或基类。

    【讨论】:

    • 但是 Observable Collections 中的类型是不同的。我是新手,所以如果我错了,我很抱歉。 Twitter集合是Facebook对象的Twitter对象和Facebook的集合。每个类都有所需的属性。 @ChrisWue
    • 非常感谢。这就是我一直在寻找的:) 还有一件事——我对内容控制器的主细节有一个想法——我现在需要绑定内容控件,那么现在如何绑定呢?我是否将它绑定到我的界面? @ChrisWue
    • 我需要使用 ContentTemplateSelector 并自己编程吗?
    • @Flipper:不是 100% 确定你的意思,但我定义了一个 ContentControl,然后你可以将它绑定到 ListBoxSelectedItem。如果您将数据模板移动到 ContentControl.Resources 中,您应该能够再次执行与 ListBox 相同的操作(根据对象的确切类型定义多个模板)
    【解决方案2】:

    在您的 ViewModel 中,创建一个公开其中一个或另一个 ObservableCollection 的属性,并在单击按钮时将其换出:

    private ObservableCollection<string> _twitterFriendList;
    private ObservableCollection<string> _facebookFriendList;
    
    private ObservableCollection<string> _selectedFriendList;
    public ObservableCollection<string> SelectedFriendList
    {
        get { return _selectedFriendList; }
        set
        {
            if (value != _selectedFriendList)
            {
                _selectedFriendList = value;
                RaisePropertyChanged("SelectedFriendList");
            }
        }
    }    
    
    void TwitterButton_Click(object sender, RoutedEventArgs e) 
    {
        SelectedFriendList = _twitterFriendList;
    } 
    
    void FacebookButton_Click(object sender, RoutedEventArgs e) 
    {
        SelectedFriendList = _facebookFriendList;
    } 
    

    然后在你的 XAML 中你可以绑定到属性:

    <ListBox ItemsSource="{Binding SelectedFriendList}"/> 
    

    【讨论】:

    • 我正在使用这样的 Observable Collection:private ObservableCollection _twitterUser;在 Twitter 用户配置文件中。可观察集合中的对象是不同的类型。 TwitterUserProfile 具有我需要的所有属性。 Facebook 有不同的属性。我是 wpf 和绑定的新手。
    • 如果两个集合包含不同类型的数据,那么在同一个ListBox 中显示它们的最佳选择是以某种方式统一它们。例如,创建一个 Twitter 和 Facebook 对象都可以实现的通用接口,并绑定到该接口。
    • 这里有一个tutorial on interfaces,详细解释了这个概念。
    【解决方案3】:

    实现此目的的一种不优雅的方法是将 2 个列表框放在同一位置,并将 1 个绑定到 twitter 集合,另一个绑定到 facebook 集合。将它们的可见性绑定到基于按钮单击而更改的属性。就个人而言,我有 2 个单选按钮,并根据选择的单选按钮显示列表框。

    <ListBox Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=TwitterCollection}" SelectedItem="{Binding Path=SelectedTwitterItem}" Visibility="{Binding Path=IsTwitterSelected, Converter={StaticResource visibilityConverter}}" />
    <ListBox Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=FacebookCollection}" SelectedItem="{Binding Path=SelectedFacebookItem}" Visibility="{Binding Path=IsFacebookSelected, Converter={StaticResource visibilityConverter}}" /> 
    
    <RadioButton Grid.Row="1" Grid.Column="0" GroupName="rdoOptions" Content="{Binding Path=TwitterLabel}" IsChecked="{Binding Path=IsTwitterSelected}" />
    <RadioButton Grid.Row="1" Grid.Column="1" GroupName="rdoOptions" Content="{Binding Path=FacebookLabel}" IsChecked="{Binding Path=IsFacebookSelected}" />
    

    【讨论】:

      猜你喜欢
      • 2018-08-13
      • 2011-05-07
      • 1970-01-01
      • 2015-06-14
      • 1970-01-01
      • 2011-08-16
      • 2012-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多