WPF Dependency Property for ItemTemplate Command

I have a custom control that defines the ItemControl and ItemTemplate for this control, i.e.

    <ItemsControl Name="ItemsControl">

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button Name="SelectionButton" Content="MyButton"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

    </ItemsControl>

      

In the code behind, I am specifying a dependency property that allows me to bind the ItemsSource property of the ItemsControl i.e.

      public static readonly DependencyProperty ButtonSourceProperty = DependencyProperty.Register(
             "ButtonSource", typeof(IEnumerable), typeof(MyControl),
             new PropertyMetadata(null, new PropertyChangedCallback(OnButtonSourceChanged))); 

      public IEnumerable ButtonSource
      {
         get { return (IEnumerable)GetValue(ButtonSourceProperty); }
         set { SetValue(ButtonSourceProperty, value); }
      }

      private static void OnButtonSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
         var buttonSelectionControl = (ButtonSelectionControl)d;
         buttonSelectionControl.ItemsControl.ItemsSource = (IEnumerable)e.NewValue;
      }

      public static void SetButtonSource(DependencyObject obj, IEnumerable enumerable)
      {
         obj.SetValue(ButtonSourceProperty, enumerable);
      }

      public static IEnumerable GetButtonSource(DependencyObject obj)
      {
         return (IEnumerable)obj.GetValue(ButtonSourceProperty);
      }

      

so in xaml i can set source for MyControl like this

<local:MyControl ButtonSource={Binding MyCollection} \>

      

This works, but how can I define a dependency property in MyControl that specifies the command to bind to in MyCollection? I currently have the following declared in xaml for command binding

Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                        CommandParameter="{Binding .}"

      

How can I abstract this so that I can set the item command to bind in the xaml like:

<local:MyControl ButtonSource={Binding MyCollection}
                 ButtonCommand={Binding MyCommand} \>

      

Pointers appreciated.

+3


source to share


2 answers


Make sure your UserControl has a dependency property for the ICommand, let's say it's called "ButtonCommand".

You may be able to bind to this inside the template for your control:

<ItemsControl Name="ItemsControl">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Name="SelectionButton" Content="MyButton" 
                    Command="{Binding ButtonCommand, RelativeSource={RelativeSource AncestorType=wpfApplication1:UserControl1}}"
                    CommandParameter="{Binding}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

      

Clicking the button should then bring up a set of commands in the "ButtonCommand" dependency property defined in your custom control.

Your ButtonCommand will define (inside your UserControl code):



public static readonly DependencyProperty ButtonCommandProperty = DependencyProperty.Register("ButtonCommand", typeof (ICommand), typeof (UserControl1), new PropertyMetadata(default(ICommand)));
public ICommand ButtonCommand { get { return (ICommand) GetValue(ButtonCommandProperty); } set { SetValue(ButtonCommandProperty, value); }}

      

Creating a command class that implements ICommand is a template, as you probably know. By putting this in your xaml button:

CommandParameter="{Binding}"

      

.. it allows you to work with a list item in your command-handling code:

public class TheCommand : ICommand
{
    public void Execute(object parameter)
    {
        var yourListItemObject = parameter as yourListItemObjectType;
    }

    // boilerplate stuff
    public bool CanExecute(object parameter) { return true; }
    public event EventHandler CanExecuteChanged;
}

      

+1


source


You can define 2 dependency properties ButtonCommmand

and ButtonCommandParameter

in UserContol.cs file and link them in UserControl xaml like this:



<UserControl x:Class="..."
             x:Name="this">
    <Button Command="{Binding ButtonCommand, ElementName=this}" 
            CommandParameter="{Binding ButtonCommandPrameter, ElementName=this}"/>
</UserControl>

      

0


source







All Articles