seanmet
Topic Author
Posts: 8
Joined: 19 Jun 2024, 10:01

Button behaviors

21 Oct 2024, 16:01

Hello, I've developed some screen that has some clickable buttons, I want my button to only fire a clicked event when it is released (which i saw is the way that the "Clicked" event works currently) , and also the event should trigger only if the release happened before some timeout (for example 1 second).

Any ideas on how i can implement such a thing?
i've tried to implement a custom behavior and i couldnt make it work, i didnt figure out how to register the behavior so that the xaml will know it.. i dont even know if its supported.

I would really appriciate your help :)

Thanks in advance!
 
User avatar
sfernandez
Site Admin
Posts: 3364
Joined: 22 Dec 2011, 19:20

Re: Button behaviors

21 Oct 2024, 18:58

A Button with its default ClickMode=Release will fire the Click event on MouseLeftButtonUp, but only if the button keeps the mouse capture. So you can for example create an action that removes the mouse capture:
class ReleaseCaptureAction: public TargetedTriggerActionT<UIElement>
{
    void Invoke(Noesis::BaseComponent* /*parameter*/) override
    {
        UIElement* target = DynamicCast<UIElement*>(GetTarget());
        if (target != 0 && target->GetIsMouseCaptured())
        {
            target->ReleaseMouseCapture();
        }
    }
    ...
};
And then execute it from a TimerTrigger:
<Grid
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
  xmlns:local="clr-namespace:Testing">
  <Grid.Resources>
  </Grid.Resources>
  <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <Button Content="Launch Animation">
      <b:Interaction.Triggers>
        <b:TimerTrigger EventName="PreviewMouseLeftButtonDown" MillisecondsPerTick="1000" TotalTicks="1">
          <local:ReleaseCaptureAction/>
        </b:TimerTrigger>
        <b:EventTrigger EventName="Click">
          <b:ChangePropertyAction TargetName="rect" PropertyName="Fill" Value="Green"/>
        </b:EventTrigger>
      </b:Interaction.Triggers>
    </Button>
    <Rectangle x:Name="rect" Height="100" Fill="Red"/>
  </StackPanel>
</Grid>
Could something like this work for you?
 
seanmet
Topic Author
Posts: 8
Joined: 19 Jun 2024, 10:01

Re: Button behaviors

22 Oct 2024, 08:17

Yes i think that could work, could you please elaborate on how do i create a custom trigger action and expose it to XAMLs?

Ive managed to create the action, but for some reason i my XAML doesnt recognize it..
This is my current code:
#ifndef NOESIS_COMMON_ACTIONS_H
#define NOESIS_COMMON_ACTIONS_H

#include <NsApp/TargetedTriggerAction.h>
#include <NsCore/RegisterComponent.h>
#include <NsGui/FrameworkElement.h>
#include <NsGui/IntegrationAPI.h>
#include <NsGui/UIElement.h>


namespace LibNoesis {
    class ReleaseCaptureAction final : public NoesisApp::TargetedTriggerActionT<Noesis::UIElement> {
    public:
        ReleaseCaptureAction() = default;
        ~ReleaseCaptureAction() override = default;


        Noesis::Ptr<Noesis::Freezable> CreateInstanceCore() const override {
            return *new ReleaseCaptureAction();
        }

        void Invoke(Noesis::BaseComponent* parameter) override
        {
            Noesis::UIElement* target = Noesis::DynamicCast<Noesis::UIElement*>(GetTarget());
            if (target != 0 && target->GetIsMouseCaptured())
            {
                target->ReleaseMouseCapture();
            }
        }
    private:
        NS_DECLARE_REFLECTION(ReleaseCaptureAction, NoesisApp::TargetedTriggerActionT<Noesis::UIElement>)

    };
}



#endif //NOESIS_COMMON_ACTIONS_H


cpp:

#include "noesis_common_actions.h"


NS_IMPLEMENT_REFLECTION(LibNoesis::ReleaseCaptureAction, "LibNoesis.ReleaseCaptureAction"){
    Noesis::RegisterComponent<ReleaseCaptureAction>();
}

and the xaml is:
<Button Width="515" Height="70" Background="#99643EBD">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Border x:Name="border" CornerRadius="35" Background="{TemplateBinding Background}">
                                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
                            </Border>
                            <!-- Triggers to change background color on Button events -->
                            <ControlTemplate.Triggers>
                                <!-- Change background color when button is pressed -->
                                <Trigger Property="IsPressed" Value="True">
                                    <Setter TargetName="border" Property="Background" Value="#FF3E8DBD"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Button.Template>
                    <TextBlock Canvas.Left="25" Canvas.Top="10" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontWeight="Bold" FontSize="38" FontFamily="/SharedFonts;component/CommonFonts/#Mont-Regular" TextAlignment="Center">
                        Start Manual Procedure
                    </TextBlock>
                    <!-- Connect command to click event -->
                    <b:Interaction.Triggers>
                        <b:TimerTrigger EventName="PreviewMouseLeftButtonDown" MillisecondsPerTick="1000" TotalTicks="1">
                          <test:ReleaseCaptureAction/>
                        </b:TimerTrigger>
                        <b:EventTrigger EventName="Click">
                            <b:InvokeCommandAction Command="{Binding StartManualProcedureCommand}" PassEventArgsToCommand="True"/>
                        </b:EventTrigger>
                    </b:Interaction.Triggers>
                </Button>
with these headers:
<UserControl
        x:Class="ForsightAssistantScreens.cAssistantHomeScreenView"
        xmlns:local_control="clr-namespace:ForsightAssistantScreens"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:b="http://schemas.microsoft.com/xaml/behaviors"
        xmlns:test="clr-namespace:LibNoesis"
        Background="Transparent">
and i get this error:
[NOESIS/E] /ScreenXaml_HomeScreen;component/AssistantMicroscopeHomeScreen.xaml(39,27): Unknown element type 'test:ReleaseCaptureAction' (LibNoesis.ReleaseCaptureAction)


Thanks!!
 
User avatar
sfernandez
Site Admin
Posts: 3364
Joined: 22 Dec 2011, 19:20

Re: Button behaviors

24 Oct 2024, 09:59

The error indicates that ReleaseCaptureAction is not properly registered. You should call Noesis::RegisterComponent<ReleaseCaptureAction>(); during your application initialization (along with the rest of component registration), instead of inside the implement reflection block.

Who is online

Users browsing this forum: Google [Bot] and 3 guests