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.

Tuesday, October 4, 2011

Realtime combobox filtering in WPF

So, imagine this:

You find yourself using WPF and you have a ComboBox bound to some data source. Your users can type what they need in the ComboBox and with the IsTextSearchEnabled and IsEditingEnables properties set to true, they can type the first few letters of the word they are searching for and the ComboBox jumps to whatever matching words start with the user's search term.

But, what if, in this combobox with an unorthodox amount of data in it, the user needs to be able to type a keyword and both be able to hide unmatched entries and have more complex searching such as filtering by object properties in the data source or showing search terms that occur anywhere in the DisplayMember property? Lambda's to the rescue!

You can hook an event up to the ComboBox's KeyUp event and apply a filter to the Items property of the ComboBox.

So, our XAML would look something like this:


<ComboBox IsEditable="True" IsTextSearchEnabled="True" ItemsSource="{Binding ComboBoxDataSource}" 
KeyUp="ComboBox_KeyUp" Text="{Binding SelectedItemText, UpdateSourceTrigger=PropertyChanged}">
and in our XAML codebehind, we would have the ComboBox_KeyUp event handler as follows:


private void ComboBox_KeyUp(object sender, KeyEventArgs e)
{
    // Ignore the user trying to scroll through filtered items using the up/down key.
    var key = e.Key;
    if(key == Key.Up || key == Key.Down) return;

    var cbo = (ComboBox)sender;
    var search = cbo.Text ?? String.Empty;

    cbo.IsDropDownOpen = true;
            
    cbo.Items.Filter = item => item.ToString().ToLower().Contains(search.ToLower());
}

So, in this code, we are taking the text that the user typed into the editable combobox and setting it to an empty string if it's null.

Then we assign a lambda expression which takes an object - called item - and check to see if the text that the user typed in, ignoring case, exists in the item.

Simple as that.

Monday, August 15, 2011

Displaying a list of installed printers in C#

Just a little snippet on grabbing a list of printers and their names in C#:

var printServer = new LocalPrintServer();
var localPrinters = printServer.GetPrintQueues(new[] {EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
var printerNames = localPrinters.Select(printer => printer.FullName).ToList();

Monday, January 3, 2011

Windows Phone 7 Development

Several months ago I began Windows Phone 7 development and found myself completely immersed in the platform. I've shied away from Android development due to my irrational disdain for Java and iPhone development simply due to my dislike for the phone. So, equipped with a background in WPF and Silverlight, C#, and the behemoth known as Visual Studio 2010, developing for the platform was actually quite enjoyable. Now that I have a development platform that I am actually quite excited about, I suppose I should document whatever tidbits of knowledge that am accumulating about this platform.

Let the snippets begin.