WinUI3 : How to trigger button click programmatically in cpp

Harshithraj1871 1,536 Reputation points
2023-11-10T07:07:59.21+00:00

Hi,

Im working on winui3 desktop application in cpp without using XAML. I wanted to trigger button click programmatically from cpp.

One option I can think of is to call the button click handler directly, but in that case we cant to see the visual experience of button being clicked.

How to solve this?

[use case : As we cant drag winui3 button, I'm placing a TextBlock on top of it with opacity set to 0. So when i drag, ill be dragging the textblock but when I click, the click will be received on TextBlock. at this time i want to make the button click happen programmatically]

Thank you

Windows App SDK
Windows App SDK
A set of Microsoft open-source libraries, frameworks, components, and tools to be used in apps to access Windows platform functionality on many versions of Windows. Previously known as Project Reunion.
783 questions
{count} votes

Accepted answer
  1. gekka 9,026 Reputation points MVP
    2023-11-11T10:23:50.33+00:00

    The visual experience of the button is caused by the different states of the pointer.
    Therefore, it is too complex to call these externally.

    For the conditions described in your use case, it would be much easier to make the button draggable.

    If you want both click and drag events to coexist, the code would look as below.

    <local:ButtonEx
        ClickMode="Release"
        Click="myButton_Click"
        Content="Drag or Click Me!">
    </local:ButtonEx>
    
    class ButtonEx : Button
    {
        protected override void OnPointerPressed(PointerRoutedEventArgs e)
        {
            if (this.CapturePointer(e.Pointer))
            {
                pressPoint = e.GetCurrentPoint(this);
    
                WireDragEvent(this);
            }
    
            base.OnPointerPressed(e);
        }
    
        private Microsoft.UI.Input.PointerPoint pressPoint;
    
        private void WireDragEvent(Button btn)
        {
            btn.PointerMoved += btn_PointerMoved;
            btn.PointerReleased += Btn_PointerReleased;
            btn.PointerCaptureLost += btn_PointerCaptureLost;
        }
        private void ReleaseDragEvent(Button btn)
        {
            btn.PointerMoved -= btn_PointerMoved;
            btn.PointerReleased -= Btn_PointerReleased;
            btn.PointerCaptureLost -= btn_PointerCaptureLost;
        }
    
        private async void btn_PointerMoved(object sender, PointerRoutedEventArgs e)
        {
            var btn = (Button)sender;
            var currentPoint = e.GetCurrentPoint(btn);
            var dx = currentPoint.Position.X - pressPoint.Position.X;
            var dy = currentPoint.Position.Y - pressPoint.Position.Y;
            var def = dx * dx + dy * dy;
            if (dx > 4)
            {
                ReleaseDragEvent(btn);
                btn.ReleasePointerCapture(e.Pointer);
    
                await btn.StartDragAsync(pressPoint);
            }
        }
    
        private void Btn_PointerReleased(object sender, PointerRoutedEventArgs e)
        {
            var btn = (Button)sender;
            ReleaseDragEvent(btn);
            btn.ReleasePointerCapture(e.Pointer);
        }
        private void btn_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
        {
            var btn = (Button)sender;
            ReleaseDragEvent(btn);
        }
    }
    

    C# and XAML used for easy make of sample.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Xiaopo Yang - MSFT 12,726 Reputation points Microsoft Vendor
    2023-11-21T05:58:30.01+00:00

    Hello @Harshithraj1871,

    RemoveHandler should use the same IInspectable as AddHandler instead of a new one.

    Windows::Foundation::IInspectable h{nullptr};
    
            h = winrt::box_value<winrt::Microsoft::UI::Xaml::Input::PointerEventHandler>({ this, &FirstPage::myButton_PointerReleased });
            b.AddHandler(winrt::Microsoft::UI::Xaml::UIElement::PointerPressedEvent(), h, true);
    
    _myB.RemoveHandler(winrt::Microsoft::UI::Xaml::UIElement::PointerPressedEvent(), h);
    
    1 person found this answer 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.