c# - 当我从 ListView 中选择项目并在WPF的UI中单击添加按钮时,如何将项目添加到列表中

标签 c# wpf listview mvvm relaycommand

我是新手,请原谅我的问题,如果它太褪色或不清楚。
无论如何,在我的UI(WPF)中,我创建了一个ListView,其中包含一个Collection = new ObservableCollection<type>类型的可观察的集合,并且我有两个按钮“添加”和“删除”,我想这样做:

1-只要我从UI的ListView中选择一个项目(只需单击它),然后单击“添加”按钮,该项目就会存储在一个名为Scenario(Scenario = new List<type>)的列表中。

2-每当我单击“删除”按钮时,方案列表将为空。

我已经尝试了一些方法,但是它不能正常工作,我只能将一个项目添加到方案场景中,然后在调试时将其阻止(调试时)
public bool CanExecute(object parameter) { return _canExecute == null || _canExecute(parameter); }
有人可以告诉我为什么吗?以及如何解决?
至于“删除”按钮,我还没明白,因为另一个按钮无法正常工作。

如果您可以提出一个新的解决方案或针对此问题的解决方案,我将非常感激。

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

这是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>

关于c# - 当我从 ListView 中选择项目并在WPF的UI中单击添加按钮时,如何将项目添加到列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43935122/

相关文章:

c# - 如何使用 SMO 创建本地数据库实例

c# - 如果类型 T 需要实例化,为什么通用类签名需要指定 new() ?

java - Android:异步填充后从数据库加载 ListView

android - 无缝嵌套滚动 (Android)

c# - GridView:Columns.Insert() 导致我的数据在回发时消失,但 Columns.Add() 工作正常吗?

c# - 错误索引超出范围。必须是非负数且小于集合的大小

c# - WPF/XAML VisualStateManager 谁处理事件?

wpf - 无法在 WPF 中完全设置 ListBox/Scrollviewer 的样式

c# - 从 AvalonDock 2.0 中的集合绑定(bind) LayoutDocument 的标题

android - 从 listView 中的选定项中获取元素