Ligação ao Comando de fora de um UserControl
-
06-07-2019 - |
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.
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.