Привязка данных WPF к общему списку‹›

Я делаю что-то не так.. вы знаете, как это бывает.

Я пробовал играть с ItemsSource , DataContext , DisplayMemberPath и SelectedValuePath, и я либо получаю пустой список списка метода ToString, вызываемого в объекте Person;

ЧТО ДЕЙСТВИТЕЛЬНО ПОМОЖЕТ, так это опубликовать ответ, который работает для этого примера.

Я упростил проблему, так как у меня вообще возникают трудности с дженериками привязки данных.

Я создал простой общий список лиц и хочу связать его с комбо. (также хочу попробовать использовать ListView).

Я либо получаю список пробелов, либо список «xxxx.Person», где xxxx = пространство имен

       <Window x:Class="BindingGenerics.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                Title="MainWindow" Height="300" Width="300">
            <Grid>

                <ComboBox Name="ComboBox1"
                          ItemsSource="{Binding}"
                          Height="50"
                          DisplayMemberPath="Name"
                          SelectedValuePath="ID"
                          FontSize="14"
                          VerticalAlignment="Top">
                </ComboBox>

            </Grid>
        </Window>



using System.Windows;
using System.ComponentModel;

namespace BindingGenerics
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Person p = new Person();
            // I have tried List and BindingList
            //List<Person> list = new List<Person>();
            BindingList<Person> list = new BindingList<Person>();

            p.Name = "aaaa";
            p.ID = "1111";
            list.Add(p);

            p = new Person();
            p.Name = "bbbb";
            p.ID = "2222";
            list.Add(p);

            p = new Person();
            p.Name = "cccc";
            p.ID = "3333";
            list.Add(p);

            p = new Person();
            p.Name = "dddd";
            p.ID = "4444";
            list.Add(p);

            ComboBox1.DataContext = list;
        }
    }

    public struct Person
    {
        public string Name;
        public string ID;
    }
}

person Adam    schedule 16.02.2010    source источник
comment
Я попробовал ваш образец, и он работает для меня. За исключением того, что он отображает dddd несколько раз.   -  person Ian Oakes    schedule 16.02.2010


Ответы (3)


В вашем примере кода Person.Name — это поле, а не свойство. Привязка данных WPF учитывает только свойства, а не поля, поэтому вам нужно изменить Person.Name на свойство.

Измените объявление Person на:

public class Person
{
  public string Name { get; set; }
  public string ID { get; set; }
}

(Для производственного кода вы, вероятно, захотите использовать ObservableCollection<Person>, а не List<Person>, и либо сделать Person неизменяемым, либо реализовать INotifyPropertyChanged — но это не является источником вашей непосредственной проблемы.)

person itowlson    schedule 16.02.2010

В показанном коде вы устанавливаете ItemsSource дважды, первый раз в XAML (вызываемом InitializeComponent) для DataContext ComboBox1, который не может быть определен из того, что вы опубликовали, но, вероятно, это не то, что вы хотите. После этого вы сбрасываете его из кода в свой объект списка (здесь с опечатками). В этом коде вы также добавляете один и тот же экземпляр Person 4 раза и снова и снова меняете его имя и идентификатор. Я подозреваю, что сочетание этих проблем и тот факт, что вы используете список вместо ObservableCollection, вызывают проблемы в вашем приложении.

Это помогло бы сузить его, если бы вы могли опубликовать реальный код, с которым вы видите проблемы, поскольку то, что вы здесь разместили, даже не компилируется.

person John Bowen    schedule 16.02.2010
comment
Пожалуйста, смотрите измененный вопрос .. с благодарностью получена любая помощь. - person Adam; 16.02.2010

Что ж... Я предполагаю, что в вашем реальном коде исправлен синтаксис, поскольку код, который вы вставили, не будет компилироваться.

Я поместил этот код в новое приложение WPF, и после создания каждого объекта Person мой список со списком заполнялся нормально. Возможно, вы захотите переместить код заполнения в событие Loaded, что обеспечит правильное построение формы. Вот исправленный xaml и отделенный код (с несколькими сокращениями синтаксиса):

xaml:

<Grid>
    <ComboBox Name="ComboBox1" Height="70"  
        DisplayMemberPath="Name"    
        SelectedValuePath="ID" />
</Grid>

код программной части:

    public Window1()
    {
        InitializeComponent();
        this.Loaded += new RoutedEventHandler(Window1_Loaded);
    }

    void Window1_Loaded(object sender, RoutedEventArgs e)
    {
        var list = new List<Person>();
        Person p = new Person(){Name = "aaaa",ID = "1111"};
        list.Add(p);
        p = new Person(){Name = "bbbb", ID="2222"};
        list.Add(p);
        p = new Person(){Name = "cccc", ID="3333"};
        list.Add(p);
        p = new Person(){Name = "dddd", ID="4444"};
        list.Add(p);
        ComboBox1.ItemsSource = list;
    }
person David Makogon    schedule 16.02.2010
comment
да .. ошибка с моей стороны .. пока я учусь вставлять код сюда .. все еще просто вызывает ToString () для Person, а не перечисляет элементы - person Adam; 16.02.2010
comment
Вы последовали совету itowlson выше и изменили свою структуру на класс, а поля на свойства? Хотя в вашем случае нет необходимости иметь класс, вы должны использовать класс, если вам когда-нибудь понадобится двусторонняя привязка, поэтому рекомендуется использовать классы все время. - person David Makogon; 17.02.2010