当我 select 列表视图中的项目并单击 WPF 上 UI 中的添加按钮时,如何将项目添加到列表

How do I add item to a list when I select the item from a listview and click add button in the UI on WPF

我是新手,所以请原谅我的问题,如果它太淡或不清楚。 无论如何,在我的 UI (WPF) 中,我创建了一个 ListView,其中包含类型 Collection = new ObservableCollection<type> 的可观察集合,并且我有两个按钮 "Add" 和 "Delete" 我想要为此:

1-每当我从 UI 中的 ListView 中 select 一个项目(只需单击它),然后单击 "Add" 按钮,该项目就会存储在一个列表中称为场景 (Scenario = new List<type>).

2- 每当我单击 "Delete" 按钮时,场景列表就会变空。

我已经尝试了一些方法,但效果不佳,我只能将一项添加到列表场景中,然后它在

中被阻止(调试时)

public bool CanExecute(object parameter) { return _canExecute == null || _canExecute(parameter); }

谁能告诉我为什么?以及如何解决? 至于 "Delete" 按钮,我还没有接触到它,因为另一个不能正常工作。

如果您能提出新的解决方案或针对此问题的解决方案,我将不胜感激。

这是我到目前为止所做的。

这是 MainWindowModel 中的代码:

private ObservableCollection<Type> _collection,_scenario;
public MainWindowModel()
{
        Collection = new ObservableCollection<type>();
        Scenario=new ObservableCollection<Type>();
        DeleteCommand = new RelayCommand(o => DeleteExecute());
        AddTypeCommand = new RelayCommand(o => AddTypeExecute());

}
private Type _isSelected;
public Type IsSelected;
{
        get { return _isSelected;  }
        set
        {
            if (_isSelected != value)
            {
                _isSelected = value;
                RaisePropertyChanged(nameof(IsSelected));

            }
        }
}
public ICommand DeleteCommand
{
        get;
        private set;
}
private RelayCommand _addTypeCommand;
public ICommand AddTypeCommand
{
        get
        {
            if (_addTypeCommand == null)
            {
                _addTypeCommand = new RelayCommand(o => AddTypeExecute());
            }
            return  _addTypeCommand;
        }
        set { }
}

private void DeleteExecute()
{
        Scenario.Clear(); // Would this Work ?
}


private bool CanExecuteAddTypeCommand()
{
        return true;
}

private void AddTypeExecute()
{
        if (IsSelected != null)
        {

            Scenario.Add(IsSelected);

        }

}
public ObservableCollection<Type> collection
{
        get { return _collection; }
        set { SetPropertyAndFireEvent(ref _collection, value); }
}
public ObservableCollection<Type> Scenario
{
        get { return _scenario; }
        set { SetPropertyAndFireEvent(ref _scenario, value); }
}

至于 MainWindowModel

<Window.DataContext>
    <viewModels:MainWindowModel />
</Window.DataContext>

<Grid>
  <ListView Grid.Row="2" 
                  Grid.Column="0"
                  ItemsSource="{Binding Collection}"
                  SelectedItem="{Binding IsSelected}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
  </ListView>

  <Button Command="{Binding AddTypeCommand}" 
                Width="100" 
                Height="100" 
                Content="Add" 
                Grid.Row="0" 
                Grid.Column="2"/>

  <Button Command="{Binding DeleteCommand}" 
                Content="Delete" 
                Width="100" 
                Height="100" 
                Grid.Row="2"
                Grid.Column="2" />
</Grid>

至于RelayCommand.cs

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;
    //Notifies the Button bounded to the ICommand that the value returned by CanExecute has changed 
    public event EventHandler CanExecuteChanged
    {
        //raised whenever the commandmanager thinks that something has changed that will affect the ability of commands to execute
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public bool CanExecute(object parameter)
    {

        return _canExecute == null || _canExecute(parameter);
    }

    public void Execute(object parameter)
    {
        _execute(parameter);
    }
}

尝试将 selectedItem 作为参数传递给命令,你不传递任何东西并尝试添加... 为您的 ListView 命名:

<ListView x:Name="listView"

并将 selectedItem 作为 commandParameter 传递

    <Button Command="{Binding AddTypeCommand}"
            CommandParameter="{Binding ElementName=listView, Path=SelectedItem}"
            Width="100"
            Height="100"
            Content="Add"
            Grid.Row="0"
            Grid.Column="2" />

然后执行添加逻辑,现在您可以将参数添加到列表中。

编辑:这是一些有效的代码,据我所知,你需要这样的代码。

ViewModel _> 创建所有集合和命令的位置:

  public class TestVM : INotifyPropertyChanged
{
    public TestVM()
    {
        ListOne = new ObservableCollection<string>()
        {
        "str1","str2","str3"
        };

        // command
        AddTypeCommand = new RelayCommand(OnAddExecute);
        DeleteTypeCommand = new RelayCommand(OnDeleteExecuted);
    }

    private void OnDeleteExecuted()
    {
        ListTwo.Clear();
    }

    private void OnAddExecute()
    {
        if (SelectedItem != null)
        {
            ListTwo.Add(SelectedItem);
        }
    }

    private string _selectedItem;
    public string SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if (_selectedItem != value)
            {
                _selectedItem = value;
                OnPropertyChanged();
            }
        }
    }

    private ObservableCollection<string> _listOne;
    public ObservableCollection<string> ListOne
    {
        get
        {
            return _listOne;
        }
        set
        {
            if (_listOne != value)
            {
                _listOne = value;
                OnPropertyChanged();
            }
        }
    }

    public ObservableCollection<string> ListTwo { get; set; } = new ObservableCollection<string>();

    public RelayCommand AddTypeCommand { get; private set; }
    public RelayCommand DeleteTypeCommand { get; private set; }


    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    public virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

RellayCommand我是如何实现的:

public class RelayCommand : ICommand
    {
        private Action _executeMethod;
        private Func<bool> _canExecuteMethod;

        #region RelayCommand ctor

        public RelayCommand(Action executeMethod)
        {
            _executeMethod = executeMethod;
        }

        public RelayCommand(Action executeMethod, Func<bool> canExecuteMethod)
        {
            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
        }

        #endregion

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }


        #region ICommand Members

        bool ICommand.CanExecute(object parameter)
        {
            if (_canExecuteMethod != null)
                return _canExecuteMethod();
            if (_executeMethod != null)
                return true;
            return false;
        }

        void ICommand.Execute(object parameter)
        {
            if (_executeMethod != null)
                _executeMethod();
        }

        public event EventHandler CanExecuteChanged = delegate { };

        #endregion
    }

    //--------------------------------------------------------------------------------------------

    public class RelayCommand<T> : ICommand
    {
        private Action<T> _executeMethod;
        private Func<T, bool> _canExecuteMethod;

        #region RelayCommand ctor

        public RelayCommand(Action<T> executeMethod)
        {
            _executeMethod = executeMethod;
        }

        public RelayCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
        {
            _executeMethod = executeMethod;
            _canExecuteMethod = canExecuteMethod;
        }

        #endregion

        public void RaiseCanExecuteChanged()
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }


        #region ICommand Members

        bool ICommand.CanExecute(object parameter)
        {
            var Tparam = (T)parameter;
            if (_canExecuteMethod != null)
                return _canExecuteMethod(Tparam);
            if (_executeMethod != null)
                return true;
            return false;
        }

        void ICommand.Execute(object parameter)
        {
            if (_executeMethod != null)
                _executeMethod((T)parameter);
        }

        public event EventHandler CanExecuteChanged = delegate { };

        #endregion
    }

和MainWindow.xaml只是为了表明目的。选择第一个列表中的一个项目并按下按钮添加会将其添加到第二个 ListView。 DeleteButton 将清除第二个列表。

<Window x:Class="WpfApp5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp5"
        mc:Ignorable="d"
        Title="MainWindow"
        Height="350"
        Width="525">
    <Window.DataContext>
        <local:TestVM />
    </Window.DataContext>
    <Grid>
        <ListView x:Name="listViewOne"
                  ItemsSource="{Binding ListOne}"
                  SelectedItem="{Binding SelectedItem,Mode=TwoWay}"
                  Width="100"
                  Height="200"
                  Margin="17,17,400,105" />
        <ListView x:Name="listViewTwo"
                  ItemsSource="{Binding ListTwo}"
                  Width="100"
                  Height="200"
                  Margin="339,17,78,105" />
        <Button Command="{Binding AddTypeCommand}"
                Content="Add"
                Grid.Row="0"
                Margin="208,111,198,178" />
        <Button Command="{Binding DeleteTypeCommand}"
                Content="Delete"
                Grid.Row="0"
                Margin="208,157,198,132" />
    </Grid>
</Window>