Почему не работает команда в User Control WPF?

Помогите, пожалуйста разобраться, почему не работает команда в кастомном UserControl WPF.

Написал вот такой вот xaml код для UserControl

<UserControl x:Class="L.Heritage.Admin.Desktop.Widgets.UI.SideBar"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d"
         d:Background="Wheat"
         x:Name="me">

<Border Padding="10">
    <StackPanel>
        <Button HorizontalAlignment="Center" 
                Content="Статьи" Margin="0, 50, 0, 10"
                Command="{Binding NavigateArticlesCommand, ElementName=me}" />
        <Button HorizontalAlignment="Center" Content="Комнаты" Margin="0, 0, 0, 10" />
        <Button HorizontalAlignment="Center" Content="Заказы" />
    </StackPanel>
</Border>

</UserControl>

XAML CS соответственно вот такой вот:

public partial class SideBar : UserControl
{
public ICommand NavigateArticlesCommand
{
    get { return (ICommand)GetValue(NavigateArticlesCommandProperty); }
    set { SetValue(NavigateArticlesCommandProperty, value); }
}

public static readonly DependencyProperty NavigateArticlesCommandProperty =
    DependencyProperty.Register("NavigateArticlesCommand", typeof(ICommand), typeof(SideBar), new PropertyMetadata(null));

public SideBar()
{
    InitializeComponent();
    DataContext = this;
}
}

Сам UserControl я использую в окне вот так:

<Window x:Class="L.Heritage.Admin.Desktop.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:widgets="clr-namespace:L.Heritage.Admin.Desktop.Widgets.UI"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/App/Routing/Routes.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <BooleanToVisibilityConverter x:Key="converter" />
    </ResourceDictionary>
    
</Window.Resources>

<DockPanel>
    
    <widgets:SideBar 
        DockPanel.Dock="Left" 
        NavigateArticlesCommand="{Binding TestCommand}"/>
    
    <!--<ContentControl Content="{Binding CurrentVM}" />-->
    
</DockPanel>

</Window>

ViewModel данного окна следующая:

public class SomeVM : ViewModelBase
{
    public TestCommand TestCommand { get; set; } = new();
}

Сама команда:

public class TestCommand : ICommand
{
public event EventHandler? CanExecuteChanged;

public bool CanExecute(object? parameter)
{
    return true;
}

public void Execute(object? parameter)
{
    throw new NotImplementedException();
}
}

При нажатии кнопка никак не реагирует, ни ошибки, ни перехода к точке останова, которую устанавливаю в команде, не происходит, помогите понять, в чем проблема.


Ответы (1 шт):

Автор решения: Uranus

Проблема здесь в том, что вы установили DataContext для SideBar на самого себя, то есть DataContext = this;. Из-за этого привязка NavigateArticlesCommand не ссылается на контекст данных окна (MainWindow) и, соответственно, не видит команду TestCommand, определенную в SomeVM.

Чтобы привязка к команде работала корректно, необходимо удалить эту строчку из конструктора SideBar, а в MainWindow установить DataContext на экземпляр SomeVM.

public MainWindow()
{
    InitializeComponent();
    DataContext = new SomeVM();
}
→ Ссылка