按钮单击ICommands时删除ListBoxItem
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了按钮单击ICommands时删除ListBoxItem相关的知识,希望对你有一定的参考价值。
我刚开始使用XAML / WPF,脑子里有很多问题。其中之一是我们如何绑定按钮单击以通过ICommand接口删除ListBoxItem
。我创建了一个简单的WPF项目,这是我的XAML:
<ListBox Name="lb" HorizontalAlignment="Left" Height="129" Margin="15,17,0,0" VerticalAlignment="Top" Width="314" Grid.ColumnSpan="2" >
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Height" Value="30" />
<Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<StackPanel Orientation="Horizontal">
<CheckBox Margin="5,5" Height="18" IsChecked="{TemplateBinding IsSelected}">
<ContentPresenter Content="{TemplateBinding Content}"/>
</CheckBox>
<Button Content="[x]" Height="22" Width="22" HorizontalAlignment="Right"
Command="{Binding ElementName=lb, Path=DataContext.DeleteItemCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}}" CommandParameter="{Binding }"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBoxItem Content="Foo" />
<ListBoxItem Content="Bar" />
</ListBox>
这是我的窗口:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new Context(); // Also tried before InitializeComponent()
}
public class Context
{
public ICommand DeleteItemCommand = new DeleteItemCommand();
}
}
DeleteItemCommand
在哪里:
public class DeleteItemCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
MessageBox.Show("Meep");
}
}
问题是:
- 为什么不显示消息框?我如何使其工作?
- 如何检索哪个索引/
ListBoxItem
触发按钮单击? - 如何将按钮对齐到行尾?
非常感谢!
你遇到的一个问题是你的ICommand只是一个变量。
你需要一个公共财产才能绑定。
更像
public ICommand DeleteItemCommand {get;set;} = new DeleteItemCommand();
另一个问题是你的元素名称。这取决于名称范围,我想你会发现列表框在另一个名称范围内。
相反,只需使用与ancestortype ListBox的relativesource绑定。
大致。
Command="{Binding DataContext.DeleteItemCommand,
RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
作为旁白。
我建议查看一个框架来使命令等更容易。
MVVMLight将是我的建议。使用nuget mvvmlightlibs添加到项目中。 https://msdn.microsoft.com/en-gb/magazine/dn237302.aspx?f=255&MSPPError=-2147217396
以下是基于我已经拥有的一些代码,因此它是说明性的而不是您正在做的事情。
视图:
<Window.DataContext>
<local:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<ListBox ItemsSource="{Binding People}"
HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding LastName}"/>
<Button Content="Delete"
Command="{Binding DataContext.DeletePersonCommand, RelativeSource={RelativeSource AncestorType=ListBox}}"
CommandParameter="{Binding}"
Grid.Column="1"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
Viewmodel使用mvvmlight的relaycommand
using GalaSoft.MvvmLight.CommandWpf;
using System.Collections.ObjectModel;
namespace wpf_99
{
public class MainWindowViewModel : BaseViewModel
{
private RelayCommand<Person> deletePersonCommand;
public RelayCommand<Person> DeletePersonCommand
{
get
{
return deletePersonCommand
?? (deletePersonCommand = new RelayCommand<Person>(
(person) =>
{
People.Remove(person);
}
));
}
}
private ObservableCollection<Person> people = new ObservableCollection<Person>();
public ObservableCollection<Person> People
{
get { return people; }
set { people = value; }
}
public MainWindowViewModel()
{
People.Add(new Person { FirstName = "Chesney", LastName = "Brown" });
People.Add(new Person { FirstName = "Gary", LastName = "Windass" });
People.Add(new Person { FirstName = "Liz", LastName = "McDonald" });
People.Add(new Person { FirstName = "Carla", LastName = "Connor" });
}
}
}
BaseViewModel就像inotifypropertychanged上的msdn文章所示:
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Mvvmlight有自己的基本视图模型,但你无法序列化vm继承自那里。
Person:public class Person:BaseViewModel {private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; RaisePropertyChanged(); }
}
private string lastName;
public string LastName
{
get { return lastName; }
set { lastName = value; RaisePropertyChanged(); }
}
以上是关于按钮单击ICommands时删除ListBoxItem的主要内容,如果未能解决你的问题,请参考以下文章