Button behaviors
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!
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!
-
-
sfernandez
Site Admin
- Posts: 3364
- Joined:
Re: Button behaviors
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:
And then execute it from a TimerTrigger:
Could something like this work for you?
Code: Select all
class ReleaseCaptureAction: public TargetedTriggerActionT<UIElement>
{
void Invoke(Noesis::BaseComponent* /*parameter*/) override
{
UIElement* target = DynamicCast<UIElement*>(GetTarget());
if (target != 0 && target->GetIsMouseCaptured())
{
target->ReleaseMouseCapture();
}
}
...
};Code: Select all
<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>Re: Button behaviors
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:
and the xaml is:
with these headers:
and i get this error:
[NOESIS/E] /ScreenXaml_HomeScreen;component/AssistantMicroscopeHomeScreen.xaml(39,27): Unknown element type 'test:ReleaseCaptureAction' (LibNoesis.ReleaseCaptureAction)
Thanks!!
Ive managed to create the action, but for some reason i my XAML doesnt recognize it..
This is my current code:
Code: Select all
#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>();
}
Code: Select all
<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>
Code: Select all
<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">
[NOESIS/E] /ScreenXaml_HomeScreen;component/AssistantMicroscopeHomeScreen.xaml(39,27): Unknown element type 'test:ReleaseCaptureAction' (LibNoesis.ReleaseCaptureAction)
Thanks!!
-
-
sfernandez
Site Admin
- Posts: 3364
- Joined:
Re: Button behaviors
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