如何在WPF中将一个“字符串列表”绑定到ComboBox?

3
我想将一个名字集合绑定到下拉框中,例如:
  • Bill
  • Jack
  • Bob
  • Kevin
我希望这些项目在一个集合中,并将其绑定到ComboBox。我不确定列表是否会动态更新,但我更喜欢为其进行计划。任何帮助都将不胜感激。我已经尝试了几个小时,但无法解决它。我想在XAML中完成,而不是在代码后台中。
MyComboBox.ItemsSource = MyObservableCollection; 

功能正常。但我不知道如何在XAML中处理在代码后台声明的集合。

提前感谢社区(再次)。

*编辑:

这是我声明和访问集合的方式。

    public ObservableCollection<string> propertynames 
    { 
        get {return _propertynames;}
    }
    private ObservableCollection<string> _propertynames;

我尝试的最后一件事是这样的:

<Window.Resources>     
    <CollectionViewSource Source="{Binding propertynames}" x:Key="srcSort"/>
</Window.Resources>
....
    <ComboBox x:Name="cboSort" HorizontalAlignment="Left" VerticalAlignment="Top" 
              Width="256" Background="WhiteSmoke" Margin="12,50,0,0" FontSize="12pt" 
              Height="27.28" 
              SelectedIndex="0" 
              SelectionChanged="cboWorkCenters_SelectionChanged"
              ItemsSource="{Binding Path = {StaticResource srcSort}}">
    </ComboBox>
....

我对这些东西完全不了解。现在只涉足IT技术一周,所以我可能做了些对于老手来说非常显然的事情。

*编辑 #2

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="clr-namespace:WpfApplication1"
    Title="Window1" Height="226" Width="242"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">

    <Grid>
        <ComboBox Margin="43,71,40,77" 
                  Name="comboBox1" 
                  ItemsSource="{Binding ob}" />
    </Grid>
</Window>

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public ObservableCollection<string> ob 
        { 
            get 
            {
                return _ob;
            }
        }
        private ObservableCollection<string> _ob = new ObservableCollection<string>();

        public Window1()
        {
            InitializeComponent();
            FillObj();
            //comboBox1.ItemsSource = ob;
        }

        private void FillObj()
        {
            for (int i = 1; i < 6; i++)
            {
                _ob.Add(i.ToString());
            }
        }
    }
}

我做了一个非常简单的项目来检查我是否完全搞错了。这个项目工作得很好,所以一定是其他原因导致它失败。
*编辑 #3 *问题已解决
天哪,我终于找到了解决方法。我花了几个小时的时间,但实际上只是一些愚蠢的错误导致了失败。
解决方法是:在声明时没有初始化 _propertynames。我通过 Linq 查询类属性以获取属性列表,然后通过将 ...GetProperties.ToList<...>() 传递给构造函数来创建 _propertynames。显然,你必须先实例化变量,这样它才能在 InitializeComponent 中使用。一旦我这样做了,并在之后添加了条目,它就正常工作了。
我希望 WPF 有一个面孔,这样我就可以打它了。我知道这是我不了解它的工作方式,但我真的需要一些提示信息。
感谢大家的帮助。一旦解决了根本问题,你们两个的建议都很有用。
private ObservableCollection<string> _propertynames

需要完成
private ObservableCollection<string> _propertynames = new ObservableCollection<string>()
2个回答

4
有无数种方法可以实现这个目标。一旦你在代码后台创建了集合,你可以:
  1. 调用Resources.Add将其添加到窗口的资源字典中,然后绑定到该资源,例如ItemsSource="{Binding {DynamicResource MyList}}"

  2. ComboBox一个名称(使用x:Name属性),并在代码中明确设置其ItemsSource,例如MyComboBox.ItemsSource = myCollection;

  3. 创建一个类,将集合作为类的属性,并将窗口的DataContext设置为该类的实例,直接绑定到它,例如ItemsSource = "{Binding MyCollectionProperty}"

  4. 将集合作为窗口的属性,将窗口的DataContext设置为this,并绑定到该属性(这本质上与#3相同,只是没有创建新的类)。

  5. 如果已经为窗口命名,即使没有设置窗口的DataContext,您仍然可以使用绑定引用其属性,例如{Binding ElementName=MyWindow, Path=MyCollection}。(这与Ross的建议相同。)

  6. 或者,不需要为窗口命名,可以使用RelativeSource绑定来查找祖先Window并绑定到其属性。我对于能否写出一个使用RelativeSource的工作绑定表达式没有信心,所以我将其留给读者作为练习。

  7. 你可以将ComboBoxDataContext设置为集合的实例,然后将其ItemsSource设置为{Binding}在实践中,你可能不会这样做;我提到它只是因为人们通常会设置控件的DataContext而没有设置绑定,然后想知道为什么绑定对象的内容没有显示出来。

(虽然上面我说的是“窗口”,但我所说的一切也同样适用于用户控件。)

我相信还有至少五种其他方法可以实现这个目标,只是我没有想到。绑定真的非常灵活。


<ComboBox ItemsSource="{Binding ElementName=Window1, Path=propertynames, Mode=OneWay}" /> 我已经尝试过这个,但它没有起作用。 - Yatrix
如果窗口的数据上下文设置为自身(在窗口的构造函数中放置“this.DataContext = this;”),则应该可以正常工作。 - Adrian
<Window x:Class=......DataContext="{Binding RelativeSource={RelativeSource Self}}}">这就是我所拥有的。这样做不能达到同样的效果吗? - Yatrix
在上面的问题中添加了更多内容。请参见编辑#2。那很好用。组合框按预期从集合中填充。 - Yatrix
“...无数种方式...<带有7个项目的编号列表>”;不管怎样,在第一个绑定中是否有遗漏的东西?即Source= - H.B.
你关于“Source”属性的观察是正确的;至于你的另一个观察,最后一段并不无关紧要。 - Robert Rossney

2

你目前尝试了什么?

如果组合框位于带有代码后台类的UserControl中,该类包含公共属性MyObservableCollection,我会采用以下方法进行处理:

<UserControl x:Name="MyCollectionOwnerControl">

    <ComboBox ItemsSource="{Binding ElementName=MyCollectionOwnerControl, Path=MyObservableCollection, Mode=OneWay}" />

</UserControl>

我编辑了原始条目并添加了更多信息。再次感谢,Ross。 - Yatrix

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接