Задать вопрос
@pig_master
C#, WPF developer

Как добавить в ListBox кнопку в начало или конец списка?

Необходимо сделать так чтобы в режиме редактирования в начале или конце списка появлялась кнопка добавления новой записи.
Что то вроде этого f1fFy.png

на данный момент есть такой код
<ListBox ItemsSource="{Binding Items}">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid/> 
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>


Попытка добавить кнопку программно (через Items.Add(button...)) налету закономерно заканчивается ошибкой - Operation is not valid while ItemsSource is in use
Как быть?
  • Вопрос задан
  • 792 просмотра
Подписаться 2 Средний 1 комментарий
Решения вопроса 1
WNeZRoS
@WNeZRoS
При бидинге коллекции к ItemsControl создаётся CollectionView (для IEnumerable, для IList - ListCollectionView), который может дополнительно отсортировать или отфильтровать коллекцию. Элементы, видимые на экране, берутся из этого CollectionView, а не из оригинальной коллекции.

ListCollectionView имеет проперти NewItemPlaceholderPosition, с помощью которого можно добавить фейковый элемент в начало или конец.
// CollectionView можно получить двумя способами:
// 1. Просто получить дефолтный вариант для коллекции
var collectionView = (ListCollectionView)CollectionViewSource.GetDefaultView(Items);
// 2. Создать свой, тогда именно этот созданный collectionView надо передавать для биндинга в ItemsSource.
var collectionView = new ListCollectionView(Models);

// После, можно добавить фейковый элемент
collectionView.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning;

После этого в ListBox появится элемент CollectionView.NewItemPlaceholder, который можно отдельно стилизовать с помощью DataTemplateSelector.

DataTemplateSelector
public sealed class NewItemTemplateSelector : DataTemplateSelector
{
   public DataTemplate ItemTemplate { get; set; }
   public DataTemplate NewItemPlaceholderTemplate { get; set; }

   public override DataTemplate SelectTemplate(object item, DependencyObject container)
   {
      if (item == CollectionView.NewItemPlaceholder)
         return NewItemPlaceholderTemplate;

      return ItemTemplate;
   }
}

<ListBox.ItemTemplateSelector>
    <t:NewItemTemplateSelector>
        <t:NewItemTemplateSelector.ItemTemplate>
            <DataTemplate>
                <!-- Шаблон обычного элемента -->
            </DataTemplate>
        </t:NewItemTemplateSelector.ItemTemplate>
        <t:NewItemTemplateSelector.NewItemPlaceholderTemplate>
            <DataTemplate>
                <!-- Шаблон CollectionView.NewItemPlaceholder -->
                <Button Content="+" />
            </DataTemplate>
        </t:NewItemTemplateSelector.NewItemPlaceholderTemplate>
    </t:NewItemTemplateSelector>
</ListBox.ItemTemplateSelector>

Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@SZolotov
Asp.net core, MAUI,WPF,Qt, Avalonia
Используйте DataTemplateSelector. Ну и почитайте про биндинг коллекций к контролам и прочие смежные штуки.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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