Есть абстрактный класс Shape
:
abstract class Shape
{
public string Name {get;set}
}
И различные классы фигур, которые наследуются от Shape
— Triangle
, 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>
Вопрос в следующем: У элементов могут быть одинаковые свойства. Как в таком случае искать нужный элемент, который требуется удалить?
Есть ли возможность получать индекс элемента, который вызвал команду?
Если у вас не перегружена функция Equals
, проще всего удалять по самому элементу. Индекс не нужен практически никогда. При удалении нужный элемент будет определяться при помощи Equals
, а значит, одинаковые свойства или нет, приниматься во внимание не будет.
Этот вариант для удаления нескольких параметров. Если же у вашего грида запрешено выделение нескольких строк и вы удаляете по одной строке. То используйте свойство 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;
}
Саму программу я заказал мне её сделали и дали код, но если препод спросит нужно объяснить что делает какая либо строкаПрограмма для слежение...
Есть у меня форма на стороне клиента с двумя выпадющими меню, он там выбирает год и тип обложки
C# WinFormThread запускается и работает, но блокирует все элементы формы