Удаление элементов из коллекции

340
21 января 2017, 09:40

Есть абстрактный класс Shape:

abstract class Shape
{
    public string Name {get;set}
}

И различные классы фигур, которые наследуются от ShapeTriangle, Circle, Square.

Также имеется коллекция фигур, которая привязывается к ListBox:

public ObservableCollection<Shape> Shapes{get;set;} = new ObservableCollection<Shape>()
{
  new Triangle {Name = "Треугольник"},
  new Circle {Name = "Круг"},
  new Circle {Name = "Круг"},
  new Square {Name = "Квадрат"},
}

Каждый объект в ListBox представлен свойством Name объекта и кнопкой, к которой биндится команда удаления элемента из коллекции. Команда одна для всех элементов.

<ListBox.ItemTemplate>
    <DataTemplate>
        <Border>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition  Width="Auto"/>
                </Grid.ColumnDefinitions>
                <TextBlock Grid.Column="0" Text="{Binding Name}" />
                <Button Grid.Column="1" Content="x" 
                        Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.RemoveShapeCommand}" 
                        CommandParameter="{Binding}" />
            </Grid>
        </Border>
    </DataTemplate>
</ListBox.ItemTemplate>

Вопрос в следующем: У элементов могут быть одинаковые свойства. Как в таком случае искать нужный элемент, который требуется удалить?

Есть ли возможность получать индекс элемента, который вызвал команду?

Answer 1

Если у вас не перегружена функция Equals, проще всего удалять по самому элементу. Индекс не нужен практически никогда. При удалении нужный элемент будет определяться при помощи Equals, а значит, одинаковые свойства или нет, приниматься во внимание не будет.

Answer 2

Этот вариант для удаления нескольких параметров. Если же у вашего грида запрешено выделение нескольких строк и вы удаляете по одной строке. То используйте свойство SelectedItem для грида:

var tempItem = SelectedItem;
SelectedItem = myList.FirstOrDefault();
myList.Remove(tempItem);

Иначе:

xaml

<Button Content="Delete" Command="{Binding Path=DeleteCommand, Mode=OneTime}"
                     CommandParameter="{Binding ElementName=MyGridName, 
Path=SelectedItems}" Width="100" Margin="10" />

command

public ICommand DeleteCommand
      {
         get
         {
            return
               _deleteCommand ?? (_deleteCommand = new CollectionCommandDelegate<MyListType>(
                  collection =>
                  {
                     var myDeleteParameters = collection != null ? collection.ToArray() : null;
                     if(myDeleteParameters!= null)
                     foreach(var myparam in myDeleteParameters)
                       myList.Remove(myparam);
                  };
         }
      }

ну и CollectionCommandDelegate public class CollectionCommandDelegate : ICommand { private readonly Action> _invoker; private readonly Func, bool> _predicate; private bool _hasChange;

    public CollectionCommandDelegate(Action<IEnumerable<T>> invoker)
    {
       _invoker = invoker;
       _predicate = arg => true;
    } 
    public CollectionCommandDelegate(Action<IEnumerable<T>> invoker, Func<IEnumerable<T>, bool> predicate)
      {
         _invoker = invoker;
         _predicate = predicate;
      }
      public void Execute(object parameter)
      {
         _invoker.Invoke(getParameter(parameter));
      }
      public bool CanExecute(object parameter)
      {
         var newState = _predicate.Invoke(getParameter(parameter));
         if (newState != _hasChange)
         {
            _hasChange = newState;
            if (CanExecuteChanged != null)
               CanExecuteChanged(this, EventArgs.Empty);
         }
         return _hasChange;
      }
      private IEnumerable<T> getParameter(object parameter)
      {
         return ((IEnumerable)parameter).Cast<T>();
      }
      public event EventHandler CanExecuteChanged;
   }
READ ALSO
Может кто объяснить, что делает каждая строка? [требует правки]

Может кто объяснить, что делает каждая строка? [требует правки]

Саму программу я заказал мне её сделали и дали код, но если препод спросит нужно объяснить что делает какая либо строкаПрограмма для слежение...

278
Как выбрать информацию из Mysql

Как выбрать информацию из Mysql

Есть у меня форма на стороне клиента с двумя выпадющими меню, он там выбирает год и тип обложки

255
SelectedItem в ListView

SelectedItem в ListView

Добрый день, есть коллекция которая заполняется из базы MySQL:

265
Форма блокируется потоком

Форма блокируется потоком

C# WinFormThread запускается и работает, но блокирует все элементы формы

361