WPF:将List<class>绑定到ComboBox

3

我已经花了大约3个小时来解决这个问题,但是我遇到了一个死路。

目前我正在尝试将列表绑定到ComboBox。

我已经尝试了几种方法来绑定列表:

后台代码:

public partial class MainWindow : Window
{
    public coImportReader ir { get; set; }

    public MainWindow()
    {          
        ir = new coImportReader();
        InitializeComponent();
    }


    private void PremadeSearchPoints(coSearchPoint sp)
    {
        //SearchRefPoint.DataContext = ir.SearchPointCollection;
        SearchRefPoint.ItemsSource = ir.SearchPointCollection;
        SearchRefPoint.DisplayMemberPath = Name;

数据绑定正确,但是由于某种原因,DisplayMemberPath 返回的是类名而不是它的成员名。
XAML 方法返回了一个空字符串...
<ComboBox x:Name="SearchRefPoint" Height="30" Width="324" Margin="0,10,0,0"
          VerticalAlignment="Top" ItemsSource="{Binding ir.SearchPointCollection}"
          DisplayMemberPath="Name">

我还尝试过用在MainWindow中创建的新列表填充它。结果两种情况都相同。
我也尝试创建ListCollectionView,成功了,但问题是我无法获取ComboBox项目的索引。我更喜欢按ID工作。因此,我正在寻找一种新的解决方案,在这里我找到了一个:http://zamjad.wordpress.com/2012/08/15/multi-columns-combo-box/ 这个例子的问题在于不清楚itemsource是如何绑定的。
编辑:
总之,我目前正在尝试绑定一个类(coImportReader)中定义的对象(coSearchPoints)的列表(SearchPointsCollection)。
namespace Import_Rates_Manager
{
    public partial class MainWindow : Window
    {
        public coImportReader ir;
        public coViewerControles vc;
        public coSearchPoint sp;

        public MainWindow()
        {
            InitializeComponent();
            ir = new coImportReader();
            vc = new coViewerControles();
            sp = new coSearchPoint();
            SearchRefPoint.DataContext = ir;
        }
   }
}

//in function.... 

SearchRefPoint.ItemsSource = ir.SearchPointCollection;
SearchRefPoint.DisplayMemberPath = "Name";

namespace Import_Rates_Manager
{
    public class coImportReader
    {      
        public List<coSearchPoint> SearchPointCollection = new List<coSearchPoint>();
    }
}

namespace Import_Rates_Manager
{
    public class coSearchPoint
    {
        public coSearchPoint()
        {
            string Name = "";
            Guid Id = Guid.NewGuid();
            IRange FoundCell = null;

        }
    }
}

这将导致一个填充的组合框,没有文本。

1
输出中有任何绑定错误吗? - Chris Mantle
不是真的,它在一个try catch中,而且我没有收到任何异常。 - Nieksa
3个回答

1

您绑定的集合需要是ir属性而不是字段。

还可以尝试这个:

public coImportReader ir { get; set; } 
public <type of SearchPointCollection> irCollection { get { return ir != null ? ir.SearchPointCollection : null; } }

绑定到irCollection并查看是否存在任何错误。

1
这是一个使用MVVM模式的简单示例。

以下是XAML代码:

<Window x:Class="Binding_a_List_to_a_ComboBox.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">
<Grid HorizontalAlignment="Left"
      VerticalAlignment="Top">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition Height="25"/>
    </Grid.RowDefinitions>

    <ComboBox Grid.Column="0" Grid.Row="0" ItemsSource="{Binding SearchPointCollection , UpdateSourceTrigger=PropertyChanged}"
              SelectedIndex="{Binding MySelectedIndex, UpdateSourceTrigger=PropertyChanged}"
              SelectedItem="{Binding MySelectedItem, UpdateSourceTrigger=PropertyChanged}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition/>
                        <RowDefinition/>
                        <RowDefinition/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{Binding Id}" Grid.Row="0"/>
                    <TextBlock Text="{Binding Name}" Grid.Row="1"/>
                    <TextBlock Text="{Binding Otherstuff}" Grid.Row="2"/>
                </Grid>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
    <Button Content="Bind NOW" Grid.Column="0" Grid.Row="1" Click="Button_Click"/>
    <TextBlock Text="{Binding MySelectedIndex, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="0"/>

    <Grid  Grid.Column="1" Grid.Row="1"
           DataContext="{Binding MySelectedItem, UpdateSourceTrigger=PropertyChanged}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="{Binding Id}" Grid.Column="0"/>
        <TextBlock Text="{Binding Name}" Grid.Column="1"/>
        <TextBlock Text="{Binding SomeValue}" Grid.Column="2"/>
    </Grid>
</Grid>

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using Import_Rates_Manager;

namespace Binding_a_List_to_a_ComboBox
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DataContext = new coImportReader();
        }    
    }
}
namespace Import_Rates_Manager
{
    public class coImportReader : INotifyPropertyChanged
    {
        private List<coSearchPoint> myItemsSource;
        private int mySelectedIndex;
        private coSearchPoint mySelectedItem;

        public List<coSearchPoint> SearchPointCollection 
        {
            get { return myItemsSource; }
            set
            {
                myItemsSource = value;
                OnPropertyChanged("SearchPointCollection ");
            }
        }

        public int MySelectedIndex
        {
            get { return mySelectedIndex; }
            set
            {
                mySelectedIndex = value;
                OnPropertyChanged("MySelectedIndex");
            }
        }

        public coSearchPoint MySelectedItem
        {
            get { return mySelectedItem; }
            set { mySelectedItem = value;
            OnPropertyChanged("MySelectedItem");
            }
        }

        #region cTor

        public coImportReader()
        {
            myItemsSource = new List<coSearchPoint>();
            myItemsSource.Add(new coSearchPoint { Name = "Name1" });
            myItemsSource.Add(new coSearchPoint { Name = "Name2" });
            myItemsSource.Add(new coSearchPoint { Name = "Name3" });
            myItemsSource.Add(new coSearchPoint { Name = "Name4" });
            myItemsSource.Add(new coSearchPoint { Name = "Name5" });
        }
        #endregion

        #region INotifyPropertyChanged Member

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion
    }

    public class coSearchPoint
    {
        public Guid Id { get; set; }
        public String Name { get; set; }
        public IRange FoundCell { get; set; }    

        public coSearchPoint()
        {
            Name = "";
            Id = Guid.NewGuid();
            FoundCell = null;    
        }
    }

    public interface IRange
    {
        string SomeValue { get; }
    }
}

以下是三个类:

  • MainWindow:将VM设置为其数据上下文
  • coImportReader:为绑定提供属性的类
  • coSearchPoint:仅作为信息容器
  • IRange:仅作为接口

非常感谢WiiMaxx,我会立即尝试 :) - Nieksa
如果你是C# -> WPF的初学者,你应该阅读WPF/MVVM快速入门教程 - WiiMaxx
@Nieksa,这个解决了你的问题吗?如果是,请将其标记为答案;否则请说明你的问题或者询问我是否有什么不清楚的地方 :-) - WiiMaxx
@Nieksa 好的,我会根据你展示的代码绑定一个可工作的示例。 - WiiMaxx
非常感谢你,WiiMaxx。我今晚会尝试一下这个。稍后我会向你报告结果。 - Nieksa

0

DisplayMemberPath 应该包含你的集合中元素的属性名称。假设 SearchPointCollection 中的元素是类型为 SearchPoint 的类,并且这个类有一个名为 SearchPointName 的属性,你应该像这样设置 DisplayMemberPath:

SearchRefPoint.DisplayMemberPath = "SearchPointName";

编辑:

在你的代码中,类coSearchPoint在构造函数中定义了字段Name。否则,绑定将无法正常工作,Name必须成为该类的属性。


感谢您的建议,Roland。您是正确的,它具有属性SearchPointName,但不幸的是,这也返回了一个空字符串。 - Nieksa
@user2606038,你能给我们提供coImportReader的代码以及集合中使用的类(SearchPoint)吗? - Roland Bär
我的ComboBox的数据上下文是否设置为主窗口?如果我定义一个新类(在主窗口中)来定义列表属性,那么ComboBox将填充属性SearchPointName。如果我将SearchPointName放在另一个类(Import_Rates_Manager)中,我需要设置ItemsSource或更好的是DataContext吗? - Nieksa
@Nieksa 我更新了我的回答。 - Roland Bär

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