1

I'm a newbie so excuse my question if it's too fade or if it's unclear. any way, In my UI (WPF), i have a ListView that i created containing an observable collection of Type Collection = new ObservableCollection<type> and i have two Buttons "Add" & "Delete" I want to do this:

1-Whenever i select an item from my ListView in the UI(just click on it) , and click the "Add" button, the item is stored in a List called Scenario (Scenario = new List<type>).

2- Whenever i click the "Delete" button the Scenario list becomes empty.

I've tried something out but it doesn't work like it should, i can only add one item to the list Scenario and then it is blocked (when debugging) in

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

Can someone tell me why? and how to fix it? As for the "Delete" Button i didn't get to it yet because the other one doesn't work properly.

if you can propose a new solution or a solution for this problem i would be so thankful.

This is what i've done so far.

This is the code in the 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); }
}

as for the 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>

As for the 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);
    }
}
AMI
  • 97
  • 12

1 Answers1

2

Try passing selectedItem as parameter for command,you dont pass anything and try to add... name your ListView:

<ListView x:Name="listView"

and pass selectedItem as commandParameter

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

and then do your logic for adding, now you have parameter to add to your list.

EDIT: Here is some code that works, as i have understand that u need something like this.

ViewModel _> where all collection and command are created:

  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 how i implement it:

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
    }

And MainWindow.xaml just to show purpose. Selecting on one item in 1rst list and pressing button Add will add it to second ListView. DeleteButton will clear second list.

<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>
ivica.moke
  • 1,054
  • 2
  • 10
  • 19