Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 删除按钮上的ListBoxItem单击图标命令_C#_Wpf_Xaml_Listbox - Fatal编程技术网

C# 删除按钮上的ListBoxItem单击图标命令

C# 删除按钮上的ListBoxItem单击图标命令,c#,wpf,xaml,listbox,C#,Wpf,Xaml,Listbox,我刚开始学习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.Re

我刚开始学习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>
其中
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();
    
    另一个问题是你的元素名。这取决于名称范围,我想你会发现列表框在另一个名称范围中

    相反,只需将relativesource绑定与ancestortype ListBox一起使用即可

    大概吧

    Command="{Binding DataContext.DeleteItemCommand,
    RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}
    
    作为旁白

    我建议研究一个框架,使命令等更容易

    MVVMLight将是我的建议。使用nuget mvvmlightlibs添加到项目

    下面是基于我已经拥有的一些代码,因此它是说明性的,而不是您正在做的事情

    视图:

    Mvvmlight有自己的基本viewmodel,但不能序列化从该模型继承的vm

    人: 公共类人员:BaseViewModel { 私有字符串名

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; RaisePropertyChanged(); }
        }
        private string lastName;
    
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; RaisePropertyChanged(); }
        }
    

    您好@Andy!谢谢您的回复。为该命令提供访问器使其正常工作。对于这个丑陋的
    相对资源
    问题,有什么解决方法吗?!还有,我如何将按钮对齐到绝对右侧?以及……我如何检索按钮的ListBoxItem索引?您意识到每个线程应该只有一个问题吗?相对资源-您可以您可能会将datacontext作为一种资源,但我建议您不要认为它看起来很难看。至少现在是这样。如果您想要右上角和左上角的内容,请使用带列的网格而不是stackpanel。不要使用索引,请将行viewmodel传递给命令CommandParameter=“{Binding}”我对WPF比较陌生,最好是一个完整的示例。在这种情况下,在同一上下文中创建多个线程没有任何意义。此外,我不知道如何“将行视图模型传递给命令”。
    
    <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>
    
    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" });
        }
    }
    }
    
    public  class BaseViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged([CallerMemberName] String propertyName = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    
        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; RaisePropertyChanged(); }
        }
        private string lastName;
    
        public string LastName
        {
            get { return lastName; }
            set { lastName = value; RaisePropertyChanged(); }
        }