Need help to pass Command property through RelayCommand to User Control by using a binding in WPF

36 Views Asked by At

I was asked to build a user control for a button, with icons, custom texblocks, etc. The thing is, I need to obviously be able to pass a command for the Button, but when I try to do it with Dependency Properties (propdp) It doesn't seem to respond to my clicks, I have tried the code (RelayCommand.cs) with a normal Button (non user control) and worked just fine.

I have seen a lot of people managing to make it work with the same or similar code as I have.

I don't know what else to do, I think my code should work, but I don't know why it doesn't.

So to explain a bit better I have created a new empty project with two buttons and a viewmodel:

I am sorry to put tons of code I couldn't get it shorter and I'm using .NET Framework 4.8.1 for this project.

MainWindows.xaml

<Window x:Class="wpfuitest1.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:local="clr-namespace:wpfuitest1"
        xmlns:userControl="clr-namespace:wpfuitest1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel>

            <userControl:boton Command="{Binding TestCommand}"
                               ButtonContent="Non working Command button"/>
            
            <Button Content="Working Command button"
                    Command="{Binding TestCommand}"></Button>
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

using System.Windows;
namespace wpfuitest1
{
    public partial class MainWindow : Window
    {
        private readonly VM vm = new VM();
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = vm;
        }
    }
}

VM.cs

using System;
namespace wpfuitest1
{
    internal class VM
    {
        public RelayCommand TestCommand => new RelayCommand(execute => Test(), canExecute => { return true; });
        public void Test()
        {
            Console.WriteLine("test");
        }
    }
}

RelayCommand.cs

using System;
using System.Windows.Input;

namespace wpfuitest1
{
    internal class RelayCommand : ICommand
    {
        private Action<object> execute;
        private Func<object, bool> canExecute;

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        public bool CanExecute(object parameter = null)
        {
            return canExecute == null | canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            execute(parameter);
        }
    }
}

boton.xaml (userControl)

<UserControl x:Class="wpfuitest1.boton"
             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" 
             xmlns:local="clr-namespace:wpfuitest1"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">

    <Button Style="{DynamicResource ButtonStyle1}" Content="{Binding ButtonContent}"
            Command="{Binding Command}">
    </Button>
</UserControl>

boton.xaml.cs

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace wpfuitest1
{
    public partial class boton : UserControl
    {
        public boton()
        {
            InitializeComponent();
            this.DataContext = this;
        }



        public string ButtonContent
        {
            get { return (string)GetValue(ButtonContentProperty); }
            set { SetValue(ButtonContentProperty, value); }
        }
        public static readonly DependencyProperty ButtonContentProperty =
            DependencyProperty.Register("ButtonContent", typeof(string), typeof(boton), new PropertyMetadata(""));


        public ICommand Command
        {
            get { return (ICommand)GetValue(CommandProperty); }
            set { SetValue(CommandProperty, value); }
        }

        public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
            "Command", typeof(ICommand), typeof(boton), new PropertyMetadata(null));
    }
}
0

There are 0 best solutions below