Friday, December 30, 2011

WP7 Mouse LongPress/Hold with Reactive Extensions (Rx)

So, I'm digging through some old code and finding whatever little snippets that I believe others may find useful.  This one in particular allows you to handle a long-press event (pressing on the screen for longer than a specified time period), which I do not believe WP7 controls have by default; it's been a while since I've touched WP7 and haven't kept up with the SDK.

Anyway, the code uses Reactive Extensions to handle this gesture.  Lets pretend that we have a control, a stackpanel perhaps.  We can use the following code to handle the user pressing and holding onto our control for 1.1 seconds:

var stackpanel = new StackPanel();

var mousedownevent = Observable.FromEvent<MouseButtonEventArgs>(stackpanel, "MouseLeftButtonDown");
var mouseupevent = Observable.FromEvent<MouseButtonEventArgs>(stackpanel, "MouseLeftButtonUp");

var mouseholdevent = mousedownevent.Delay(TimeSpan.FromSeconds(1.1)).TakeUntil(mouseupevent).Repeat();

mouseholdevent.Subscribe(x => MessageBox.Show("LongPress with Rx!"));

I just thought this was something cool with reactive extensions so I decided to share it with everyone :)

Segmenting IEnumerable into equal-sized chunks

A while ago, I found myself submitting data to a server, but the data needed to be chunked before being submitted; the reason for this was that server only allowed approximately 50 values to be submitted at a time.  The data was in a class inheriting from IEnumerable, so I figured why not write a simple extension method to segment data.  Easy peasy, but useful if needed.

public static class Extensions
{
    public static IEnumerable<IEnumerable<T>> Segment<T>(this IEnumerable<T> data, int segmentSize)
    {
        double dataSize = data.Count();
        var segmentCount = segmentSize == 0 ? 0 : (int)Math.Ceiling(dataSize / segmentSize);
        return Enumerable.Range(0, segmentCount).Select(i => data.Skip(i * segmentSize).Take(segmentSize));
    }
}

Using the extension method is as easy as:

var segments = Enumerable.Range(1, 10).Segment(3);

The results of running the above code is as follows:


Probably not the best solution since it does iterate over the collection multiple times, but it gets the job done.  Enjoy.