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));
}
}