How to add IsPressed effect to a Control?

William Liu 466 Reputation points
2024-09-04T00:33:54.49+00:00

I would like to create a custom control which is inherited from Control. But Control doesn`t have the IsPressed DP as Button. I want to change the background of my control when it is pressed. However, I don't like to bring other properties which Button has, so I choose Control as base.

Could you let me know how to add IsPressed effect to a Control?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,760 questions
0 comments No comments
{count} votes

Accepted answer
  1. Hongrui Yu-MSFT 1,600 Reputation points Microsoft Vendor
    2024-09-04T05:32:58.15+00:00

    Hi,@William Liu. Welcome to Microsoft Q&A. 

    If you want your custom control to inherit Control and have an IsPressed event, you could register the IsPressed event in your custom control, and then use System.Windows.Interactivity.WPF to monitor the MouseDown event and trigger the IsPressed event.

     

    Registering for the IsPressed event.

    
    public static readonly RoutedEvent IsPressedEvent = EventManager.RegisterRoutedEvent("IsPressed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CustomControl));
    
     
    
    public event RoutedEventHandler IsPressed
    {
        add { AddHandler(IsPressedEvent, value); }
        remove { RemoveHandler(IsPressedEvent, value); }
    }
    
    

     

    Use System.Windows.Interactivity.WPF to listen and trigger the IsPressed event.

    Install System.Windows.Interactivity.WPF via NuGet.

    
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.windows.Interactivity"
    
     
    
    <ControlTemplate TargetType="{x:Type local:CustomControl}">
    
        <Border Background="DimGray" BorderBrush="Black" BorderThickness="10" Width="200" Height="50">
    
            <i:Interaction.Triggers>
    
                <i:EventTrigger EventName="MouseDown">
    
                    <i:InvokeCommandAction Command="{Binding relayCommand}"></i:InvokeCommandAction>
    
                </i:EventTrigger>
    
            </i:Interaction.Triggers>
    
        </Border>
    
    </ControlTemplate>
    
    

     

    
    public class CustomControl : Control
    {
                    public RelayCommand relayCommand {  get; set; }
    
                    public CustomControl()
    				{
    
                           this.DataContext = this;
    					   relayCommand = new RelayCommand(OnButtonClick);
    				}
    				public void OnButtonClick()
    				{
        					RaiseEvent(new RoutedEventArgs(IsPressedEvent));
    				}
    				//Other parts of the code
    }
    
    

     

    Complete code

     

    Generic.xaml

    
    <ResourceDictionary
        …
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.windows.Interactivity"
        >
    
        <Style TargetType="{x:Type local:CustomControl}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type local:CustomControl}">
                        <Border Background="DimGray" BorderBrush="Black" BorderThickness="10" Width="200" Height="50">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="MouseDown">
                                    <i:InvokeCommandAction Command="{Binding relayCommand}"></i:InvokeCommandAction>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </ResourceDictionary>
    
    

     

    CustomControl.cs

    
    public class CustomControl : Control
    {
        public RelayCommand relayCommand {  get; set; }
    
        public static readonly RoutedEvent IsPressedEvent = EventManager.RegisterRoutedEvent("IsPressed", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CustomControl));
    
        public event RoutedEventHandler IsPressed
        {
            add { AddHandler(IsPressedEvent, value); }
            remove { RemoveHandler(IsPressedEvent, value); }
        }
    
        public void OnButtonClick()
        {
            RaiseEvent(new RoutedEventArgs(IsPressedEvent));
        }
    
        public CustomControl()
        {
            this.DataContext = this;
            relayCommand = new RelayCommand(OnButtonClick);
        }
    
        static CustomControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl), new FrameworkPropertyMetadata(typeof(CustomControl)));
        }
    }
    
    

    RelayCommand.cs

    
    public class RelayCommand : ICommand
    {
        public Action action {  get; set; }
     
        public RelayCommand(Action action)
        {
            this.action = action;
        }
    
        public event EventHandler? CanExecuteChanged;
    
        public bool CanExecute(object? parameter)
        {
            return true;
        }
     
        public void Execute(object? parameter)
        {
            action.Invoke();
        }
    }
    
    

     

    MainWindow.xaml

    <Grid>
        <local:CustomControl IsPressed="CustomControl_MyCustom"></local:CustomControl>
    </Grid>
    
    

     

    MainWindow.xaml.cs

    
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    
        private void CustomControl_MyCustom(object sender, RoutedEventArgs e)
        {
            MessageBox.Show("haha");
        }
    }
    
    

    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.