2009-07-31 2 views
4

У меня есть простой UserControl, содержащий Label, ComboBox и Button. Короче говоря, он должен использоваться практически во всех моих представлениях много раз, каждый раз поставляемый с различными ItemsSource и CreateItemCommand с использованием Bindings для моих свойств ViewModel.Привязка к команде извне пользователя UserControl

Этикетка и ComboBox являются частью другого UserControl (LabeledComboBox), который работает отлично.

Проблема заключается в том, что, когда я пытаюсь связать команду в окне, которое содержит мой UserControl я получаю следующее исключение:

A «Связывание» не может быть установлен на свойстве «CreateItemCommand» типа ' MutableComboBox. «Связывание» может быть установлено только на DependencyProperty объекта DependencyObject.

Вот XAML для MutableComboBox:

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

Как вы можете видеть, я использую два различных подхода к регистрации своих DPs: 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 который обеспечивает ObservableCollection получателей и ICommand CreateNewRecipient как простые свойства.

Что я делаю неправильно? Единственное, что я хочу в этом конкретном случае, - это открыть свойство Button.Command для использования вне моего UserControl, как и ItemsSource. Я пытаюсь использовать команды неправильно? Как я могу привязать команды моего UserControls к другим элементам управления или окнам?

Считайте меня новым с этой командой и материалом DependencyProperty. Любая помощь будет оценена по достоинству. Гугл всю ночь и не нашел ничего полезного в моем случае. Простите мой английский.

ответ

7

Вы зарегистрировали неправильное имя для своей зависимости. Это должно быть:

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

Примечание: строка является «CreateItemCommand». Вы должны прочитать через this MSDN documentation подробную информацию о соглашениях для свойств зависимостей.

+0

Спасибо! Вот и все. Предположим, мне нужно больше узнать о том, как это работает. Единственное, что я знал, это то, что он должен быть уникальным в пространстве имен. Итак, каковы критерии для имени в DependencyProperty.Register()? Просто удалить слово Property из имени в объявлении или что-то еще? – dvn

+1

Нет проблем. Я добавил ссылку на мой ответ, который поможет вам понять это. –

+0

Ссылка больше не доступна. – eYe