user2837961
user2837961

Reputation: 1555

ICommand Button binding in Itemcontrol

Have xaml.cs file containing my ObservableCollection of my ViewModel. I have now implemented a command binding to a button click which invokes my function inside the viewmodel. The problem is that I do not get the item of my list in my button click function

xaml

<ItemsControl ItemsSource="{Binding ConditionList}" AlternationCount="{Binding ConditionList.Count}">
 <ItemsControl.ItemTemplate>
  <DataTemplate>
   <WrapPanel>
    <Button Content="{Binding}" Command="{Binding DataContext.DeleteCondition, 
    RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" CommandParameter="{Binding}" />
   </WrapPanel>
  </DataTemplate>
 </ItemsControl.ItemTemplate>
</ItemsControl>

Please note my button is in ItemControl

VM

    private void DoDeleteCondition(object parameter)
    {
      //  if (parameter != null)
      //      ...
    }

    public ICommand DeleteCondition
    {
        get
        {
            if (_DeleteCondition == null) 
                _DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
            return _DeleteCondition;
        }
    }

Upvotes: 1

Views: 160

Answers (2)

Arie
Arie

Reputation: 5373

I have a feeling that your binding is set a little backwards.

In your ItemsControl do you want to have:

  1. the items from your collection and one command that will execute when you click on the single item
  2. or the list of possible commands you want to execute on a single item that you have elsewhere (meaning the collection is displayed on some parent element, so you can bind to the single item somehow)?
  3. ... or maybe you have a separate command defined for every item in your collection ...? (then, how are the elements in your collection implemented?)

Depending on your answer:

1:

 <ItemsControl ItemsSource="{Binding Path=MyObservableCollection}" >
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <WrapPanel>
                            <Button Content="{Binding}"
                                    Command="{Binding Path=DataContext.DeleteCondition, RelativeSource={RelativeSource AncestorType=AncestorWithYourViewModelAsDataContext}}" 
                                    CommandParameter="{Binding}" />
                        </WrapPanel>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>

2:

<ItemsControl ItemsSource="{Binding Path=ConditionList}" >
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <Button Content="{Binding}" 
                                Command="{Binding Path=MyConditionalCommand}"
                                CommandParameter="{BindingToTheElementOfYourCllectionThatYouWantToActUpon}" />
                    </WrapPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

example implementation in your ViewModel:

private List<ConditionalCommand> _ConditionList;

        public List<ConditionalCommand> ConditionList
        {
            get { return _ConditionList; }
            set
            {
                if (_ConditionList != value)
                {
                    _ConditionList = value;
                    OnPropertyChanged("ConditionList");
                }
            }
        }

...

class ConditionalCommand
{
        public ICommand MyConditionalCommand { get; set; }
        public string Name { get; set; }
        public override string ToString()
        {
            return Name;
        }

}

...

 this.ConditionList = new List<ConditionalCommand>();
  this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteCondition , Name="Delete"});
  this.ConditionList.Add(new ConditionalCommand{ MyConditionalCommand = DeleteSpecial, Name="Delete special" });

....

private void DoDeleteCondition(object parameter)
    {
      //  if (parameter != null)
      //      ...
    }

    public ICommand DeleteCondition
    {
        get
        {
            if (_DeleteCondition == null) 
                _DeleteCondition = new RelayCommand(o => DoDeleteCondition(o));
            return _DeleteCondition;
        }
    }

// DeleteSpecial implemented in similar manner...

Upvotes: 0

Amit Raz
Amit Raz

Reputation: 5536

You need to create a RelayCommand<T> where T is the Item in the ConditionList. Then you will get your parameter in the execute method.

Upvotes: 2

Related Questions