Pregunta

Tengo un UserControl simple que contiene Label, ComboBox y Button. En resumen, se debe usar en casi todas mis vistas muchas veces, cada vez que se suministra con diferentes ItemsSource y CreateItemCommand utilizando enlaces a mis propiedades ViewModel.

Label y ComboBox son parte de otro UserControl (La LabelComboBox) que funciona bien.

El problema es que cuando intento vincular un comando en una ventana que contiene mi UserControl obtengo la siguiente excepción:

  

No se puede establecer un 'Enlace' en la propiedad 'CreateItemCommand' del tipo 'MutableComboBox'. Un 'Enlace' solo se puede establecer en una DependencyProperty de un DependencyObject.

Aquí está el XAML para 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>

Aquí está el código subyacente para ello:

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
}

Como puede ver, utilizo dos enfoques diferentes para registrar mis DP: ItemsSource se toma de ItemsControl DP y CreateItemCommand es creado por DependencyProperty.Register (...). Intenté usar Button.CommandProperty.AddOwner (...) pero tuve la misma excepción.

Así es como trato de enlazar:

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

El DataContext de la ventana se establece en ViewModel apropiado que proporciona una Colección de destinatarios observable y un ICommand CreateNewRecipient como propiedades simples.

¿Qué estoy haciendo mal? Lo único que quiero en este caso particular es exponer una propiedad Button.Command para usarla fuera de mi UserControl, al igual que ItemsSource. ¿Estoy tratando de usar los comandos de manera incorrecta? ¿Cómo puedo vincularme a comandos de mis UserControls desde otros controles o ventanas?

Considérame un novato con estas cosas de Command and DependencyProperty. Cualquier ayuda sería apreciada. Busqué en Google toda la noche y no encontré nada útil en mi caso. Perdón por mi inglés.

¿Fue útil?

Solución

Ha registrado un nombre incorrecto para su propiedad de dependencia. Debería ser:

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

Tenga en cuenta que la cadena es " CreateItemCommand " ;. Debe leer esta documentación de MSDN para obtener información detallada sobre las convenciones para propiedades de dependencia.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top