.netwpfxamlbindingrelativesource

RelativeSource never called


I want to bind a command which is in the code behind to user control button(ICommand) which is in UserControl.Resources

So I wrote a code using RelativeSource. But It didn't work.

I tried to solve this using converter for debugging.

But even this wasn't called.

Here is the code I made. Please tell me if I'm wrong.

Thank you.

XAML

<UserControl x:Class="Views.Common.SubMenuPanel"
             xmlns:controls="...."                
             ....
             mc:Ignorable="d">

<UserControl.Resources>            
    <controls:SubMenuButton x:Key="TerminateSystem" 
                            ButtonName="Terminate System" 
      [[DOESN'T WORK]] -->  Execute="{Binding RelativeSource={RelativeSource  AncestorType={x:Type UserControl}}, Path=TerminateSystemCommand
                                    , Converter={StaticResource DebugDummyConverter}}"
                            ImageURI="...png"/>       

    <CollectionViewSource x:Key="LoginViewSubMenuItems">
        <CollectionViewSource.Source>
            <system:ArrayList>
                <StaticResource ResourceKey="TerminateSystem"/>
            </system:ArrayList>
        </CollectionViewSource.Source>
    </CollectionViewSource>
</UserControl.Resources>

<Grid>
   <ListBox ItemsSource="{Binding Source={StaticResource LoginViewSubMenuItems}}"/>
</Grid>

Code Behind

public partial class SubMenuPanel : UserControl
{
     public ICommand TerminateSystemCommand => new RelayCommand(() => Do Something);

     public SubMenuPanel()
     {
        InitializeComponent();

        this.DataContext = this;
     }
}

Solution

  • You are binding the ICommand to an Execute property. The property you should be binding to is Command, i.e.

    <controls:SubMenuButton x:Key="TerminateSystem" 
                            ButtonName="Terminate System" 
                            Command="{Binding RelativeSource={RelativeSource  AncestorType= 
                                     {x:Type UserControl}}, Path=TerminateSystemCommand
                                        , Converter={StaticResource DebugDummyConverter}}"
                           ImageURI="...png"/> 
    

    Assuming the other properties in the button are not causing other issues, that should resolve it.

    EDIT:

    I am including the code I have verified to work. Since I don't have your definition for SubMenuButton, I just used a Button instead:

    XAML:

    <UserControl.Resources>
        <Button x:Key="TerminateSystem" 
                Command="{Binding RelativeSource={RelativeSource  AncestorType={x:Type UserControl}}, Path=TerminateSystemCommand}">
            Say Hello World!!!!
        </Button>
        <CollectionViewSource x:Key="LoginViewSubMenuItems">
            <CollectionViewSource.Source>
                <system:ArrayList>
                    <StaticResource ResourceKey="TerminateSystem"/>
                </system:ArrayList>
            </CollectionViewSource.Source>
        </CollectionViewSource>            
    </UserControl.Resources>
    
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource LoginViewSubMenuItems}}"/>
    </Grid>
    

    Code behind:

    public ICommand TerminateSystemCommand =>
            new RelayCommand(() => Console.WriteLine("Hello World!!!"));