Как настроить ItemSource и ItemTemplate для отображения списка объектов

#wpf #list #data-binding #mvvm #itemtemplate

#wpf #Список #привязка данных #mvvm #itemtemplate

Вопрос:

У меня есть окно списка, в котором я хочу отобразить список объектов, я следую шаблону MVVM и мне трудно достичь того, чего я хочу.

MainWindowView.xaml

 <ListBox ItemsSource="{Binding Path=MyList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Path=Name}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
 

MainWindowViewModel.cs

     private List<ListBoxItem> _myList = new List<ListBoxItem>();

    public List<ListBoxItem> MyList
    {
        get { return _myList ; }
        set
        {
            _myList = value;
            OnPropertyChanged("MyList");
        }
    }

    public SprintBacklogViewModel()
    {
        foreach(MyObject obj in MyObjects.MyObjectList)
        {
            ListBoxItem item = new ListBoxItem();
            item.Content = obj;
            MyList.Add(item);
        }
    }
 

myList обновляется правильно, но в окне ничего не отображается. (ItemsSource=»{Binding Path=myList}» также работает, я тестировал с разными данными) Я раньше не использовал ItemTemplate, поэтому любые указатели приветствуются. Я понимаю, что если я настрою его правильно, он будет отображать данные в моих объектах.
например:

 <Label Content="{Binding Path=Name}"/>
 

в MyObject есть свойство с именем Name, я хочу отобразить его как метку в моем списке

* РЕДАКТИРОВАТЬ В моем окне я получаю строку текста — mynamespace.MyObject

Ответ №1:

Свойство myList в ViewModel является свойством типа ListBoxItem, у него есть имя свойства, но это не имя MyObject . Итак, вам нужно изменить свое свойство в вашей ViewModel на

Заменить

 private List<ListBoxItem> _myList = new List<ListBoxItem>();

public List<ListBoxItem> MyList
{
    get { return _myList ; }
    set
    {
        _myList = value;
        OnPropertyChanged("MyList");
    }
}
 

с

 private List<MyObject> _myList = new List<MyObject>();

public List<MyObject> MyList
{
    get { return _myList ; }
    set
    {
        _myList = value;
        OnPropertyChanged("MyList");
    }
}
 

Ответ №2:

  1. Ваш список должен содержать не элементы пользовательского интерфейса, а данные (вы привязаны к данным), если вы привязываетесь к списку ListBoxItems ListBox , игнорируйте ItemTemplate и просто используйте элементы, поскольку они соответствуют ожидаемому контейнеру для ListBox . Контейнеры будут сгенерированы автоматически, вам не нужно делать это в вашем списке.
  2. Если вы добавляете элементы в коллекцию во время выполнения, механизм привязки должен получать уведомления об обновлении изменений, для этого вы должны использовать ObservableCollection или что-либо, что реализует INotifyCollectionChanged . (При этом вы дополнительно обычно создаете поле readonly и предоставляете только средство получения) Это причина, по которой нет элементов.