WPF, связывающий с данными с объектом коллекции

Argh, хотя я гуглил, я действительно, ценил бы его, если кто-то мог бы сломать мою проблему, поскольку все примеры кода онлайн смущают меня больше, чем помощь (возможно, просто поздно)...

У меня есть простой класс, как определено ниже:

public class Person
{
    int _id;
    string _name;

    public Person()
    { }

    public int ID
    {
        get { return _id; }
        set { _id = value; }
    }

    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

это хранится в базе данных, и через немного большее количество кода я поместил ее в объект ObservableCollection попытаться связать с данными в WPF позже:

 public class People : ObservableCollection<Person>
{
    public People() : base() { }

    public void Add(List<Person> pListOfPeople)
    {
        foreach (Person p in pListOfPeople) this.Add(p);
    }
}

В XAML у меня есть самостоятельно ListView, что я хотел бы заполнить ListViewItem (состоящий из textblock) для каждого объекта у "Людей" объект, поскольку он обновляется от базы данных. Я также хотел бы, чтобы это textblock связало со свойством "Name" объекта Человека.

Я думал сначала, что мог сделать это:

lstPeople.DataContext = objPeople;

где lstPeople является моим управлением ListView в моем XAML, но это, конечно, ничего не делает. Я нашел ТОННЫ примеров онлайн, где люди через XAML создают объект и затем связывают с ним через их XAML; но не тот, где мы связываем с инстанцированным объектом и перерисовкой соответственно.

Мог кто-то давать мне несколько подсказок по:

A) Как связать управление ListView с моими инстанцированными "Людьми" объект коллекции?

B) Как я мог бы применить шаблон к своему ListView для форматирования его для объектов в наборе?

Даже ссылки на достойный пример (не одна работа на объекте, объявленном в XAML), ценились бы.

Спасибо за внимание.

9
задан Randster 27 May 2010 в 07:13
поделиться

3 ответа

Вы были так близки.

lstPeople.ItemsSource = objPeople; // :)

Единственное, что вам нужно, это как применить представление для каждого элемента в вашей коллекции. Без проблем. Я не буду использовать ListView ... Я просто буду использовать ItemsControl, потому что это немного проще.

<ItemsControl x:Name="lstPeople">
    <ItemsControl.ItemTemplate>
         <DataTemplate>
              <TextBlock Text="{Binding Name}" />
         </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Это почти все. Стратегия такая же для Listview, но вам нужно предоставить чуть больше XAML для предоставления заголовков столбцов и прочего. Я не уверен на 100%, что вам это нужно в данный момент, поэтому я не упомянул об этом.

Изменить: Вот метод расширения для «AddRange», который будет делать то, что вы пытаетесь сделать, создавая подкласс ObservableCollection. Немного проще ... особенно, если у вас будет много типов коллекций (у вас будет)

public static void AddRange<T>(this ObservableCollection<T> collection, IEnumerable<T> items)
{
     foreach(var item in items)
     {
          collection.Add(item);
     }
}

Тогда вы можете просто сделать:

ObservableCollection<Person> peeps = new ObservableCollection<Person>();
peeps.AddRange(new List<Person>
{ 
     new Person() { Name = "Greg" }, 
     new Person() { Name = "Joe" } 
});
8
ответ дан 4 December 2019 в 22:27
поделиться

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

Одно я все же добавлю: нет необходимости определять новый тип коллекции, который наследуется от ObservableCollection, вместо этого вы можете просто сделать вот так:

ObservableCollection<Person> myPeopleCollection = new ObservableCollection<Person>();

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

0
ответ дан 4 December 2019 в 22:27
поделиться

Действительно, ответ 'Anderson Imes' правильный (upvote), хотя у меня есть два замечания:

Во-первых, если вам нужно отобразить только одно свойство объекта, я думаю, что проще и чище использовать ListBox вместо ListView, потому что код для привязки свойства будет сокращен до

<ListBox x:Name="lstPeople" DisplayMemberPath="Name" />

Во-вторых, если вы используете WPF и Binding, убедитесь, что ваши объекты реализуют INotifyPropertyChanged, чтобы изменения всегда синхронизировались между UI и объектами.

public class Person : INotifyPropertyChanged
{
    int _id;
    string _name;

    public Person()
    { }

    public int ID
    {
        get { return _id; }
        set { 
             _id = value; 
             RaisePropertyChanged("ID");
            }
    }

    public string Name
    {
        get { return _name; }
        set { 
             _name = value;  
             RaisePropertyChanged("Name");
            }
    }

    pivate void RaisePropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }

}
0
ответ дан 4 December 2019 в 22:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: