WPF依赖属性用于ItemTemplate命令

3

我有一个用户控件,它为该控件定义了一个ItemsControl和一个ItemTemplate,即:

    <ItemsControl Name="ItemsControl">

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

    </ItemsControl>

在代码后面,我指定了一个依赖属性,使我能够绑定ItemsControl的ItemsSource属性,即:
      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);
      }

这样,在XAML中,我可以设置MyControl的源如下:
<local:MyControl ButtonSource={Binding MyCollection} \>

这样可以工作,但是我如何在MyControl中定义一个依赖属性,以指定要绑定到MyCollection中的命令?目前我在XAML中声明了以下内容来进行命令绑定。
Command="{Binding DataContext.MyCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
                        CommandParameter="{Binding .}"

我该如何将此抽象化,以便我可以在XAML中绑定到要绑定的项命令,类似于以下内容:
<local:MyControl ButtonSource={Binding MyCollection}
                 ButtonCommand={Binding MyCommand} \>

指针赞赏。
2个回答

1

确保您的UserControl具有依赖属性到一个ICommand,假设这个属性被称为"ButtonCommand"。

您应该能够在您控件的模板内绑定到此属性:

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

按钮点击后,应该触发在您的用户控件中定义的“ButtonCommand”依赖属性中设置的命令。
您的ButtonCommand定义(在UserControl代码内部)如下所示:
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); }}

创建一个实现ICommand接口的命令类是样板式的东西,你可能已经知道了。通过将此放入您的按钮XAML中:

CommandParameter="{Binding}"

它将允许您在命令处理代码中使用列表中的项目:

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;
}

还有些困惑。我在哪里定义你上面写的 ControlTemplate?在 UserControl1 中吗?如果每次在 xaml 中使用 UserControl1 都要定义一次,那就有点违背初衷了,但我觉得我可能误解了。 - James B
我猜因为你正在使用UserControl,所以会有所不同。我会更新答案。 - James Harcourt

0
你可以在UserControl的.cs文件中定义2个依赖属性ButtonCommmandButtonCommandParameter,并在UserControl的xaml中绑定它们,如下所示:
<UserControl x:Class="..."
             x:Name="this">
    <Button Command="{Binding ButtonCommand, ElementName=this}" 
            CommandParameter="{Binding ButtonCommandPrameter, ElementName=this}"/>
</UserControl>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接