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), ценились бы.
Спасибо за внимание.
Вы были так близки.
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" }
});
@Anderson опередил меня на несколько секунд, мой ответ был очень похож.
Одно я все же добавлю: нет необходимости определять новый тип коллекции, который наследуется от ObservableCollection, вместо этого вы можете просто сделать вот так:
ObservableCollection<Person> myPeopleCollection = new ObservableCollection<Person>();
единственный раз, когда вы хотите расширить его, это если вы собираетесь делать с ним что-то другое или причудливое, чего вы, похоже, не делаете.
Действительно, ответ '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));
}
}