2009-07-31 11 views
4

Ich habe ein einfaches UserControl mit Label, ComboBox und Button. Kurz gesagt, es ist in fast allen meinen Ansichten oft zu verwenden, jedes Mal mit verschiedenen ItemsSource und CreateItemCommand mit Bindings zu meinen ViewModel-Eigenschaften.Binding to Command von außerhalb eines UserControl

Das Label und ComboBox sind Teil eines anderen UserControl (LabeledComboBox), die gut funktioniert.

Das Problem ist, dass wenn ich versuche, einen Befehl in einem Fenster zu binden, dass mein Usercontrol enthält erhalte ich die folgende Ausnahme:

A ‚Bindung‘ kann nicht auf der ‚CreateItemCommand‘ Eigenschaft des Typs eingestellt werden ' MutableComboBox '. Eine 'Bindung' kann nur für eine DependencyProperty eines DependencyObject festgelegt werden. Hier

ist das XAML für 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> 

Hier ist der Code-Behind für sie:

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 
} 

Wie Sie sehen können, verwende ich zwei verschiedene Ansätze zur Registrierung meine DPs: Itemssource wird von ItemsControl DP übernommen und CreateItemCommand wird von DependencyProperty.Register (...) erstellt. Ich habe versucht, Button.CommandProperty.AddOwner (...) zu verwenden, hatte aber die gleiche Ausnahme.

Hier ist, wie ich zu binden versuchen:

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

Die Datacontext des Fensters gesetzt Ansichtsmodell anzueignen, die eine ObservableCollection von Empfängern und eine ICommand CreateNewRecipient als einfache Eigenschaften bietet.

Was mache ich falsch? Das einzige, was ich in diesem speziellen Fall möchte, ist, eine Button.Command-Eigenschaft für die Verwendung außerhalb meines Benutzersteuerelements verfügbar zu machen, genau wie die ItemsSource. Versuche ich Befehle falsch zu benutzen? Wie kann ich Befehle von anderen Steuerelementen oder Fenstern an meine Benutzersteuerelemente binden?

Betrachten Sie mich als Newb mit diesem Befehl und DependencyProperty stuff. Jede Hilfe wäre willkommen. Die ganze Nacht gegoogelt und in meinem Fall nichts brauchbares gefunden. Entschuldige mein Englisch.

Antwort

7

Sie haben den falschen Namen für Ihre Abhängigkeitseigenschaft registriert. Es sollte sein:

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

Beachten Sie die Zeichenfolge ist "CreateItemCommand". Sie sollten this MSDN documentation für detaillierte Informationen zu den Konventionen für Abhängigkeitseigenschaften lesen.

+0

Vielen Dank! Das war's. Angenommen, ich muss mehr darüber lesen, wie es funktioniert. Das einzige, was ich wusste, war, dass es innerhalb eines Namensraums eindeutig sein muss. Was sind die Kriterien für einen Namen in DependencyProperty.Register()? Einfach das Wort Property vom Namen in der Deklaration oder etwas anderem entfernen? – dvn

+1

Kein Problem. Ich habe einen Link zu meiner Antwort hinzugefügt, der Ihnen helfen soll, dies zu verstehen. –

+0

Der Link ist nicht mehr verfügbar. – eYe

Verwandte Themen