Pergunta

Eu tenho um UserControl simples contendo Etiqueta, ComboBox e Button. Em suma, é para ser usado em quase todos os meus Visualizações muitas vezes, cada vez fornecido com diferentes ItemsSource e CreateItemCommand usando ligações aos meus propriedades ViewModel.

A Etiqueta e ComboBox são parte de outro UserControl (LabeledComboBox), que funciona muito bem.

O problema é que quando eu tento ligar um comando em uma janela que contém o meu UserControl recebo a seguinte exceção:

A 'ligação' não pode ser definido na propriedade 'CreateItemCommand' do tipo 'MutableComboBox'. A 'binding' só pode ser definido em uma DependencyProperty de um DependencyObject.

Aqui está o 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>

Aqui está o codebehind para isso:

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 você pode ver, eu uso duas abordagens diferentes para registrar meus PD: ItemsSource é tomada de ItemsControl DP e CreateItemCommand é criado por DependencyProperty.Register (...). Eu tentei usar Button.CommandProperty.AddOwner (...), mas teve a mesma exceção.

Aqui está como eu tentar vincular:

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

O DataContext da janela é definida como apropriar ViewModel que fornece uma ObservableCollection de destinatários e um ICommand CreateNewRecipient como propriedades simples.

O que estou fazendo de errado? A única coisa que eu quero neste caso particular é expor uma propriedade Button.Command para uso fora do meu UserControl, assim como o ItemsSource. Estou tentando usar comandos de forma errada? Como posso vincular aos comandos de meus UserControls de outros controles ou janelas?

Considere-me um newb com este material de Comando e DependencyProperty. Qualquer ajuda seria apreciada. Pesquisei toda a noite e não encontrou nada de útil no meu caso. Pardon meu Inglês.

Foi útil?

Solução

Você registrou o nome errado para o seu propriedade de dependência. Ele deve ser:

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

Observe a string é "CreateItemCommand". Você deve ler este documentação do MSDN para obter informações detalhadas sobre as convenções para propriedades de dependência.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top