简体   繁体   English

WPF:绑定列表 <class> 到一个ComboBox

[英]WPF: Binding a List<class> to a ComboBox

I've been working on this problem for about 3 hours now, and I got to a dead end. 我现在已经解决了这个问题大约3个小时了,我走到了尽头。 Currently I'm trying to bind a list to a ComboBox. 目前我正在尝试将列表绑定到ComboBox。

I have used several methods to bind the List: 我使用了几种方法来绑定List:

Code behind: 代码背后:

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;

The data was binded correctly but the DisplayMemeberPath for some reason returned the name of the class and not the name of it's member. 数据已正确绑定,但DisplayMemeberPath由于某种原因返回了类的名称而不是其成员的名称。

The XAML method returned an empty string... XAML方法返回一个空字符串...

<ComboBox x:Name="SearchRefPoint" Height="30" Width="324" Margin="0,10,0,0"
          VerticalAlignment="Top" ItemsSource="{Binding ir.SearchPointCollection}"
          DisplayMemberPath="Name">

I've also tried to fill it with a new list which I create in the MainWindow. 我还尝试用MainWindow中创建的新列表填充它。 the result was the same in both cases. 结果在两种情况下都是一样的。

Also I've tried to create and ListCollectionView which was success, but the problem was that I could get the index of the ComboBox item. 此外,我尝试创建和ListCollectionView这是成功的,但问题是,我可以得到ComboBox项目的索引。 I prefer to work by an Id. 我更喜欢用Id工作。 For that reason I was looking for a new solution which I found at: http://zamjad.wordpress.com/2012/08/15/multi-columns-combo-box/ 出于这个原因,我正在寻找一个新的解决方案,我在以下网址找到:http: //zamjad.wordpress.com/2012/08/15/multi-columns-combo-box/

The problem with this example is that is not clear how the itemsource is being binded. 这个例子的问题是不清楚itemsource是如何绑定的。

Edit: 编辑:

To sum things up: I'm currently trying to bind a list(SearchPointsCollection) of objects(coSearchPoints) defined in a class (coImportReader). 总结一下:我目前正在尝试绑定一个类(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;

        }
    }
}

This results in a filled combobox with no text 这导致填充的组合框没有文本

The Collection you are binding to needs to be a property of ir not a field. 你绑定的集合需要是一个属性而不是一个字段。

Also try this : 也试试这个:

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

Bind to irCollection and see what errors you get if any. 绑定到irCollection并查看您获得的错误(如果有)。

Here a simple example using the MVVM Pattern 这是一个使用MVVM模式的简单示例

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

Code

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; }
    }
}

Here are 3 Classes: 这是3个类:

  • MainWindow which set VM as his Datacontext MainWindow将VM设置为他的Datacontext
  • coImportReader the Class which presents your properties for your bindings coImportReader提供绑定属性的类
  • coSearchPoint which is just a Container for your information coSearchPoint ,它只是一个容器,供您参考
  • IRange which is just an Interface IRange只是一个接口

The DisplayMemberPath should contain the property name of the elements in your collection. DisplayMemberPath应包含集合中元素的属性名称。 Assuming the elements in the SearchPointCollection are of the type SearchPoint and this class has a Property SearchPointName you should set DisplayMemberPath like this: 假设在元素SearchPointCollection是类型SearchPoint这个类有一个属性SearchPointName您应该设置DisplayMemberPath这样的:

SearchRefPoint.DisplayMemberPath = "SearchPointName";

Edit: 编辑:

In your code the class coSearchPoint has the Field Name defined in the Constructor. 在您的代码中,类coSearchPoint具有在构造函数中定义的字段Name Name has to be a Property of the class, otherwise the Binding can't work. Name必须是类的Property,否则Binding不能工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM