Windows 8 / XAML Double Tap event always preceded by Tap - c#

I've got a button in an app. I want it to do different things depending on whether I tap it (pause an animation) or double-tap (restart the animation)
however, when I double-tap, it seems to fire the tap event first and then the double-tap in quick succession. Is there a way around this? Is this a known issue or am I making a rookie mistake?
Edit: For those asking, I'm using the Tapped and DoubleTapped events.

Give the some pause to single tab . If there is double tab occur then single tab event eliminated
bool singleTap;
private async void control_Tapped_1(object sender, TappedRoutedEventArgs e)
{
this.singleTap = true;
await Task.Delay(200);
if (this.singleTap)
{
// Single tab Method .
}
}
private void control_DoubleTapped_1(object sender, DoubleTappedRoutedEventArgs e)
{
this.singleTap = false;
// Double tab Method
}

You might want to consider letting it do both. Think about it like double clicking a folder in windows. Users will be used to something happening on the first click (highlighting the folder) and they will be expecting the double click to both highlight, then navigate.
All in all it seems like a design issue, not a technical one.

[System.Runtime.InteropServices.DllImport("user32.dll")]
static extern uint GetDoubleClickTime();
bool _singleTapped = false;
//Tapped event handler
private async void control_Tapped(object sender, TappedRoutedEventArgs e)
{
_singleTapped = true;
//var x = GetDoubleClickTime();
//GetDoubleClickTime() gets the maximum number of milliseconds that can elapse between a first click and a second click
await Task.Delay(TimeSpan.FromMilliseconds(GetDoubleClickTime()));
if (!_singleTapped)
{ return; }
//SingleTapped code
}
//DoubleTapped event handler
private async void control_DoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
_singleTapped = false;
//DoubleTapped code
}

Related

Long Press Detector with c# in xamarin.forms

I am making a simple calculator app where the DEL button removes the last digit in the viewport, but if held down for one second it deletes everything in the viewport. Right now If I press the button once, it deletes the last digit whether I hold it down or not. If I press it down again (held down or just a regular tap) it clears everything in the viewport and I cannot type anything else in.
Firstly I create the timer like so:
public System.Timers.Timer timer = new System.Timers.Timer(1);
and then I have a function for when the 'DEL' button is pressed:
private void DeletePressed(object sender, EventArgs args)
{
timer.Stop();
timer.Start();
timer.Elapsed += AllClear;
}
a function to stop the timer and delete the last character from the viewport when the button is released:
private void DeleteReleased(object sender, EventArgs args)
{
timer.Stop();
if (CalculatorString.Length > 0)
{
CalculatorString = CalculatorString.Remove(CalculatorString.Length - 1);
}
viewport.Text = CalculatorString;
}
and finally the procedure that is called when the timer finishes:
private void AllClear(Object Source, System.Timers.ElapsedEventArgs e)
{
timer.Stop();
CalculatorString = "";
viewport.Text = CalculatorString;
}
however none of what I expected tohas happened. I appreciate any help in advance :)
There is no direct way to listen long press in Xamarin.Forms(PCL). You have to write separate custom renderers for each platform to Listen long press and communicate it to the PCL.
You can refer this link for code example for doing the same.

stopping event from code C#, call event by user not by code

Sorry, this may be a duplicate question, but I couldnot understand the solutions already provided in different answers.
I have created a mp3 player in a different manner, it plays one mp3 file at a time but one listbox have the chapters, which is not only handling to move position of that particular mp3 but also changes a picturebox image. Now somewhere I need to change the selection of the listbox from a seekbar but dont want to fire the following event of;
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
Please guide.
One way to inhibit your selection indexed change event doing its normal way is to use a boolean flag. Also, make sure that this inhibition does not stay around when some exception is raised:
private bool inhibit = true;
private void doSomeProcessWithInhibit()
{
try
{
inhibit = true;
// processing comes here
}
// if something goes wrong, make sure other functionality is not blocked
finally
{
inhibit = false;
}
}
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
// fast return to reduce nesting
if (inhibit)
return;
// do event handling stuff here
}
P.S. Try to use meaningful names for controls (check listBox1). You will thank yourself when revisiting the code and/or others have to.
Add a Boolean with class scope called something like isProcessing. Set it to true. Do your work, then set it to false. Warp your event in the Boolean:
bool isProcessing = true;
private void switchControls(){
isProcessing = true;
//do work;
isProcessing = false;
}
private void MyControl.OnEvent(object sender, EventArgs e){
if(!isProcessing){
//what you would normally do
}
}
OR....
Deregister the event, the re-register it
private void switchControls(){
myButton1.OnClick -= myButtonClick;
//do work
myButton1.OnClick += myButtonClick;
}

React to Button.IsPressed WPF

I'd like to have a TextBlock changed when the button is pressed, and then return to the previous state when the button is released.
It appears that RepeatButton is not a solution here, as it only reacts to itself being held and not released - and I need to know when it is released so that I can run a proper method to return TextBlock to its original state. Being desperate I also tried to loop while(button.IsPressed) (yeah, I know, awful idea :() but to no avail - the code would hang (as if IsPressed did not change to false after the button had been released).
Is there any way to achieve it? Thanks in advance.
Maybe not the cleanest way, but I decided to create multiple handlers to my button: Click, PointerPressed, PointerCancelled, PointerCaptureLost, PointerReleased. First two are for handling the button being pressed, while the last three are for handling the release. I used all three due to recommendation here:
http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.uielement.pointerreleased
This is because PointerReleased may sometimes be substituded by other events being fired at button release.
PreviewMouseDown and PreviewMouseUp seem to work fine, if you want both left and right click to have your desired effect:
public partial class MainWindow : Window
{
private string TextBlockPreviousState = "";
public MainWindow()
{
InitializeComponent();
ButtonStatusTextBlock.Text = "foo";
}
private void StoreAndUpdate()
{
TextBlockPreviousState = ButtonStatusTextBlock.Text;
ButtonStatusTextBlock.Text = "Button Down";
}
private void Restore()
{
ButtonStatusTextBlock.Text = TextBlockPreviousState;
}
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
StoreAndUpdate();
}
private void Button_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
Restore();
}
}

how to avoid click when I want double click?

I have an application in WPF and one button. In this buttun I want the click event that implement a code, but I want that when the do double click with the mouse, execute other code but not the code of the click event.
The problem is that the code of the click event is always executed and I don't know if there is a way to avoid the execution of the click event when I do doulbe click.
I am follow the MVVM pattern and I use MVVM light to convert the event into a command.
Thanks.
On the click event, you can check the amount of clicks in the EventArgs, for example;
private void RightClickDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
//do single click work here.
}
if (e.ClickCount == 2)
{
//do double click work.
}
}
This means you can differentiate between single and double clicks manually, if that's what you desire.
Set the RoutedEvent's e.Handled to True after handling the MouseDoubleClick event to block second click events of being fired.
If you want to block first click event behavior, you can use a timer:
private static DispatcherTimer myClickWaitTimer =
new DispatcherTimer(
new TimeSpan(0, 0, 0, 0, 250),
DispatcherPriority.Normal,
mouseWaitTimer_Tick,
Dispatcher.CurrentDispatcher) { IsEnabled = false };
private void Button_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Stop the timer from ticking.
myClickWaitTimer.Stop();
Trace.WriteLine("Double Click");
e.Handled = true;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
myClickWaitTimer.Start();
}
private static void mouseWaitTimer_Tick(object sender, EventArgs e)
{
myClickWaitTimer.Stop();
// Handle Single Click Actions
Trace.WriteLine("Single Click");
}
Here is a nice explanation on how to distinguish between clicks and double clicks. And it gives you 2 example on how you can achieve that.
I shared this solution, that is a mix between the two others solutions. I can't give the accepted solution to both, sorry.
If I use the PreviewMouseLeftButtonDown to control when is single click or double click works, instead of using two events (click and doubleclick).
So I solve the problem with this code:
This first method control the click with the mouse.
private void MouseLeftButtonDownCommand(MouseButtonEventArgs e)
{
if (e.ClickCount == 1)
{
_dtMouseClick.Start();
}
else if(e.ClickCount > 1)
{
_dtMouseClick.Stop();
//the code of the double click
}
}
This method is the method that is linked to the DispatcherTimer, that is execute if is not stopped with the second click of the mouse.
private void MouseClick_Tick(object sender, System.EventArgs e)
{
_dtrMouseClick.Stop();
//code of the single click
}
The dispatcherTimer is create in the constructor of the view model
_dtBotonBuscarMouseClick =
new System.Windows.Threading.DispatcherTimer(
new TimeSpan(0, 0, 0, 0, 250),
System.Windows.Threading.DispatcherPriority.Background,
MouseClick_Tick,
System.Windows.Threading.Dispatcher.CurrentDispatcher);
_dtMouseClick.Stop();
The interval is 250ms that is the interval that is the time that the user has to double click.
In this solution, I use the same way to stop the dispatcherTimer, the stop() method, but for some reason if I use the two events (click and mouseDoubleClick) the dispatcherTimer is not stopped in the double click and if I use the MouseLeftButtonDown event the solution works.

Windows C# CheckedListBox Checked Item Event Handling

I'm currently developing a Window app that uses CheckedListBoxes for certain aspects of the program. A problem I've encountered is that I have been trying to find which event is triggered when an item is checked so that I can enable a form button when any list item is checked.
Problem is that I tried using the following;
private void clbAvailMods_ItemCheck(object sender, ItemCheckEventArgs e)
{
if(e.NewValue == CheckState.Checked)
{
btnInstall.Enabled = true;
}
}
but when I set a breakpoint on the if statement, it never fires upon checking an item in the listbox.
Am I doing something wrong here?
A standard Windows Forms trick is to delay running code until all event side-effects have been completed. You delay running code with the Control.BeginInvoke() method. This will fix your problem:
private void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) {
this.BeginInvoke(new MethodInvoker(evalList), null);
}
private void evalList() {
bool any = false;
for (int ix = 0; ix < checkedListBox1.Items.Count; ++ix) {
if (checkedListBox1.GetItemChecked(ix)) {
any = true;
break;
}
}
btnInstall.Enabled = any;
}
You can use the NewValue property to manually update CheckedItems.Count. This is the code I use to only enable a button when there's at least one item checked:
private void checkedListBoxProds_ItemCheck(object sender, ItemCheckEventArgs e)
{
this.buttonGenerar.Enabled = ((this.checkedListBoxProds.CheckedItems.Count + (e.NewValue == CheckState.Checked ? 1 : -1)) > 0);
}
A couple of potential gotchas. Presumably you've added the event through the VS.Net GUI to ensure that it gets plumbed into the control. Try clicking on an item twice - once to give the item focus and again to toggle the check state - if you want an item to have its check state toggled on first click then set the "CheckOnClick" property to true.
I think it is the SelectedIndexChanged event but I will confirm right now.
EDIT: SelectedIndexChanged event does work. But that is firing regardless of whether the checkbox was checked. So I would then check the checked state if you want to do that.
But as an aside when I did use the ItemCheck event it did fire when I actually checked the checkbox and not just the text.
I know this has been answered long ago, but I found it easier to just handle the MouseUp and KeyUp events. The CheckedItems.Count property is accurate when those events are fired. Since they both do the same thing, I created a method to to the work and called that method from both event handlers.
private void clbFolders_KeyUp(object sender, KeyEventArgs e) { Update(); }
private void clbFolders_MouseUp(object sender, MouseEventArgs e) { Update(); }
private void Update()
{
btnDelete.Enabled = clbFolders.CheckedItems.Count > 0;
}

Categories

Resources