从UserControl外部绑定到命令

4
我有一个简单的UserControl,包含标签、组合框和按钮。简言之,它将在我的许多视图中使用很多次,每次都使用绑定到我的ViewModel属性的不同ItemsSource和CreateItemCommand。
标签和组合框是另一个UserControl(LabeledComboBox)的一部分,它运行正常。
问题在于,当我尝试在包含我的UserControl的窗口中绑定命令时,会出现以下异常:
“Binding”不能设置在MutableComboBox类型的CreateItemCommand属性上。只能在DependencyObject的DependencyProperty上设置“Binding”。
下面是MutableComboBox的XAML:
<UserControl x:Class="Albo.Presentation.Templates.MutableComboBox"
x:Name="MCB"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:uc="clr-namespace:Albo.Presentation.Templates" >
<StackPanel Height="25" Orientation="Horizontal">
    <uc:LabeledComboBox x:Name="ComboBoxControl"
        Label = "{Binding ElementName=MCB, Path=Label}"
        ItemsSource="{Binding ElementName=MCB, Path=ItemsSource}"
        SelectedItem="{Binding ElementName=MCB, Path=SelectedItem}" />
    <Button x:Name="CreateItemButton"
        Grid.Column="1" Width="25" Margin="2,0,0,0"
        Content="+" FontFamily="Courier" FontSize="18" 
        VerticalContentAlignment="Center"
        Command="{Binding ElementName=MCB, Path=CreateItemCommand}"/>
</StackPanel>
</UserControl>

这是它的代码后台:
```

在此处放置其代码:

```
public partial class MutableComboBox : UserControl
{
    public MutableComboBox()
    {
        InitializeComponent();
    }

    public string Label
    {
        get { return this.ComboBoxControl.Label; }
        set { this.ComboBoxControl.Label = value; }
    }

    #region ItemsSource dependency property
    public static readonly DependencyProperty ItemsSourceProperty =
        ItemsControl.ItemsSourceProperty.AddOwner(
            typeof(MutableComboBox),
            new PropertyMetadata(MutableComboBox.ItemsSourcePropertyChangedCallback)
        );

    public IEnumerable ItemsSource
    {
        get { return (IEnumerable)GetValue(ItemsSourceProperty); }
        set { SetValue(ItemsSourceProperty, value); }
    }

    public static void ItemsSourcePropertyChangedCallback(
        DependencyObject controlInstance,
        DependencyPropertyChangedEventArgs e)
    {
        MutableComboBox myInstance = (MutableComboBox)controlInstance;

        myInstance.ComboBoxControl.ItemsSource = (IEnumerable)e.NewValue;
    } 
    #endregion // ItemsSource dependency property

    #region SelectedItem dependency property
    // It has just the same logic as ItemsSource DP.
    #endregion SelectedItem dependency property

    #region CreateItemCommand dependency property

    public static readonly DependencyProperty CreateItemCommandProperty =
        DependencyProperty.Register(
            "MutableComboBoxCreateItemCommandProperty",
            typeof(ICommand),
            typeof(MutableComboBox)
        );

    public ICommand CreateItemCommand
    {
        get { return (ICommand)GetValue(CreateItemCommandProperty); }
        set { SetValue(CreateItemCommandProperty,value); }
    }

    #endregion // CreateItem dependency property
}

正如您所看到的,我使用两种不同的方法来注册我的DP:ItemsSource取自ItemsControl DP,而CreateItemCommand则是通过DependencyProperty.Register(...)创建的。我尝试使用Button.CommandProperty.AddOwner(...),但出现了相同的异常。

这里是我尝试进行绑定的方式:

<Window ...
    xmlns:uc="clr-namespace:Albo.Presentation.Templates">
    <uc:MutableComboBox Label="Combo" 
        ItemsSource="{Binding Path=Recipients}"
        CreateItemCommand="{Binding Path=CreateNewRecipient}"/>
</Window>

窗口的DataContext设置为适当的ViewModel,该ViewModel提供了一个ObservableCollection的Recipients和一个ICommand CreateNewRecipient作为简单属性。
我做错了什么?在这种情况下,我想要的唯一一件事是将Button.Command属性公开供我的UserControl之外的控件使用,就像ItemsSource一样。我是否在错误地使用命令?如何从其他控件或窗口绑定到我的UserControls的命令?
请把我当成一个新手,对于这个Command和DependencyProperty的东西一无所知。任何帮助都将不胜感激。我整晚都在Google上搜索,但没有找到任何可用的内容。请原谅我的英语。
1个回答

7

您注册的依赖属性名称不正确,应该是:

public static readonly DependencyProperty CreateItemCommandProperty =
        DependencyProperty.Register(
            "CreateItemCommand",
            typeof(ICommand),
            typeof(MutableComboBox)
        );

请注意,字符串是“CreateItemCommand”。您应该阅读此MSDN文档,了解依赖属性的约定详细信息。

谢谢!就这些了。假设我需要了解更多关于它的工作原理。我唯一知道的是它必须在命名空间内是唯一的。那么 DependencyProperty.Register() 中名称的标准是什么?只需从声明中删除 Property 单词或还有其他要求吗? - dvn
1
没问题。我在我的答案中添加了一个链接,应该可以帮助你理解这个问题。 - Kent Boogaart
1
该链接已不再可用。 - eYe

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