如何绑定“列表” WPF 中的 ComboBox 的字符串?

发布于 2024-11-26 16:00:03 字数 3201 浏览 1 评论 0原文

我基本上想在集合中获取一堆名称并将它们绑定到组合框。例如:

  • Bill
  • Jack
  • Bob
  • Kevin

将这些项目放入集合中并将其绑定到组合框。我不确定该列表是否会动态更新,但我更愿意计划它。任何帮助将不胜感激。我已经尝试了几个小时了,但无法弄清楚。我想在 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>
....

我对这些东西一窍不通。已经使用了大约一周,所以我可能做了一些对于经验丰富的用户来说非常明显的事情。

*编辑#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>()

I basically want to take a bunch of names in a collection and bind them to a combobox. For example:

  • Bill
  • Jack
  • Bob
  • Kevin

and have those items in a collection and have it bound to the ComboBox. I'm not sure if the list will be updated dynamically or not, but I prefer to plan for it to be. Any help would be appreciated. I've been trying for a few hours now and can't figure it out. I want to do it in XAML and not the code-behind. In the code-behind,

MyComboBox.ItemsSource = MyObservableCollection; 

works fine. I don't know how to do that in XAML though with the collection declared in the code-behind.

Thanks in advance (again), community.

*EDIT:

This is how I have the collection declared and accessible.

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

The last thing I tried was this:

<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>
....

I'm a total n00b to this stuff. Been in it about a week now, so I may have done something really obvious to a seasoned user.

*EDIT #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());
            }
        }
    }
}

Made above real simple project just to see if I was doing it all wrong. This worked fine so something else must be causing it to fail.

*EDIT #3
*PROBLEM FIXED

For God's sake, I figured it out. I've been on this for HOURS and it's just silly what's caused it to fail.

The solution is this: I wasn't instantiating _propertynames when I declared it. I was querying the class properties with Linq to get the list of properties and then created _propertynames by passing ...GetProperties.ToList<...>() to the constructor. Apparently, you have to instantiate the variable so it hits during InitializeComponent. Unreal.
Once I did that and then added the items to it after the fact, it worked fine.

I wish WPF had a face so I could punch it. I know it's my ignorance of how it works, but I really could have used some kind of message.

Thanks guys for the help. Both of your suggestions were useful once I took care of the root issue.

private ObservableCollection<string> _propertynames

needs to be

private ObservableCollection<string> _propertynames = new ObservableCollection<string>()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

远山浅 2024-12-03 16:00:03

有无数种方法可以做到这一点。在代码隐藏中创建集合后,您可以:

  1. 调用 Resources.Add 将其添加到窗口的资源字典中,然后绑定到资源,例如 ItemsSource ="{绑定{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 }。 (这与罗斯的建议相同。)

  6. 或者,在不给窗口命名的情况下,您可以使用 RelativeSource 绑定来查找祖先 Window 并绑定到其上的财产。我对自己编写一个使用 RelativeSource 的有效绑定表达式的能力没有任何信心,所以我将把它作为练习留给读者。

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

(虽然我在上面提到了“窗口”,但我所说的一切也适用于用户控件。)

我确信至少还有五种我没有想到的其他方法可以做到这一点。绑定确实非常灵活。

There are countless ways of doing this. Once you've created the collection in code-behind, you can:

  1. Call Resources.Add to add it to the window's resource dictionary, and then bind to the resource, e.g. ItemsSource="{Binding {DynamicResource MyList}}".

  2. Give the ComboBox a name (using the x:Name attribute) and set its ItemsSource explicitly in code, e.g. MyComboBox.ItemsSource = myCollection;.

  3. Create a class, make the collection a property of the class, and set the window's DataContext to an instance of that class and bind to it directly, e.g. ItemsSource = "{Binding MyCollectionProperty}".

  4. Make the collection a property of the window, set the window's DataContext to this, and bind to the property (this is essentially the same technique as #3, only you're not creating a new class).

  5. Without setting the window's DataContext, you can still reference a property on it using binding as long as you've given it a name, e.g. {Binding ElementName=MyWindow, Path=MyCollection}. (This is the same as Ross's suggestion.)

  6. Or, without giving the window a name, you can use RelativeSource binding to find the ancestor Window and bind to a property on it. I don't have any confidence in my ability to write a working binding expression that uses RelativeSource off the top of my head, so I'll leave that as an exercise for the reader.

  7. You can set the DataContext of the ComboBox to the instance of your collection, and then set itsItemsSource to {Binding}. You probably wouldn't do this in practice; I mention it just because it seems to be a common mistake for people to set the DataContext of a control without also setting a binding, and then wonder why content from the bound object isn't showing up.

(While I've said "window" in the above, everything I've said is also true for user controls.)

I'm sure there are at least five other ways to do this that I'm not thinking of. Binding is really, really flexible.

风轻花落早 2024-12-03 16:00:03

到目前为止你尝试过什么?

我将按如下方式处理它,假设组合框位于 UserControl 中,并且具有包含 public 属性 MyObservableCollection 的代码隐藏类:

<UserControl x:Name="MyCollectionOwnerControl">

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

</UserControl>

What have you tried so far?

I would approach it as follows, assuming the combo box is within a UserControl with a code-behind class containing the public property MyObservableCollection:

<UserControl x:Name="MyCollectionOwnerControl">

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

</UserControl>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文