Domanda

Ho un semplice UserControl contenente Label, ComboBox e Button. In breve, deve essere utilizzato in quasi tutte le mie viste molte volte, ogni volta fornito con diversi ItemsSource e CreateItemCommand usando i collegamenti alle mie proprietà ViewModel.

Label e ComboBox fanno parte di un altro UserControl (LabeledComboBox) che funziona perfettamente.

Il problema è che quando provo a associare un comando in una finestra che contiene il mio UserControl ottengo la seguente eccezione:

  

Non è possibile impostare un 'Binding' sulla proprietà 'CreateItemCommand' di tipo 'MutableComboBox'. Un "Binding" può essere impostato solo su DependencyProperty di DependencyObject.

Ecco XAML per 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>

Ecco il codebehind per questo:

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
}

Come puoi vedere, utilizzo due approcci diversi per la registrazione dei miei DP: ItemsSource è preso da ItemsControl DP e CreateItemCommand è creato da DependencyProperty.Register (...). Ho provato a usare Button.CommandProperty.AddOwner (...) ma ho avuto la stessa eccezione.

Ecco come provo a legare:

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

Il DataContext della finestra è impostato su ViewModel appropriato che fornisce un oggetto ObservableCollection di destinatari e un ICommand CreateNewRecipient come proprietà semplici.

Cosa sto facendo di sbagliato? L'unica cosa che voglio in questo caso particolare è esporre una proprietà Button.Command da usare al di fuori del mio UserControl, proprio come ItemsSource. Sto cercando di usare i comandi nel modo sbagliato? Come posso associare i comandi dei miei controlli utente da altri controlli o finestre?

Considerami un principiante con questa roba Command and DependencyProperty. Qualsiasi aiuto sarebbe apprezzato. Ho cercato su Google tutta la notte e non ho trovato nulla utilizzabile nel mio caso. Perdonate il mio inglese.

È stato utile?

Soluzione

Hai registrato il nome sbagliato per la tua proprietà di dipendenza. Dovrebbe essere:

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

Nota che la stringa è " CreateItemCommand " ;. È necessario leggere questa documentazione MSDN per informazioni dettagliate sulle convenzioni per proprietà di dipendenza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top