Software Design Engineer
| | Sun | Mon | Tue | Wed | Thu | Fri | Sat |
|---|
| 26 | 27 | 28 | 29 | 30 | 31 | 1 | | 2 | 3 | 4 | 5 | 6 | 7 | 8 | | 9 | 10 | 11 | 12 | 13 | 14 | 15 | | 16 | 17 | 18 | 19 | 20 | 21 | 22 | | 23 | 24 | 25 | 26 | 27 | 28 | 29 | | 30 | 1 | 2 | 3 | 4 | 5 | 6 |
Search
Navigation
Categories
Blogroll
|

Tuesday, November 18, 2008
Resetting the Selected Item of a Silverlight 2 ListBox Control
Silverlight version: 2.0.31005.0
If you are trying to reset the selected item of a ListBox control using either the SelectedItem or SelectedIndex properties, it will not work with the version of Silverlight stated above. From what I can glean in the Silverlight forums, this method did at one time work (previous release candidate maybe) and is also a known issue that is being addressed (for the current version).
In the meantime, you can adapt your application to use another existing control or custom control, or you could do something like the following:
Option 0: Reset the selected item or index outside of your SelectionChanged event handler. One way to do this is to use a DispatcherTimer. When the ListBox SelectionChanged event fires, start the timer. In the Tick handler, stop the timer and perform the reset (set SelectedItem to null or SelectedIndex to -1).
Drawbacks: this isn’t unexpected, but resetting the selected item is reflected by the ListBox UI, so the last selected ListBox item may not be as noticeable to the user. If you want to show the last selected item AND enable clicking on the same item multiple times in sequence, then see the option below.
Option 1: You can also reset the selected item without resorting to the use of an additional timer. Simply take advantage of the Dispatcher.BeginInvoke method like in the following code ('lb' refers to a ListBox instance):
Dispatcher.BeginInvoke(new Action(delegate() { lb.SelectedItem = null; }));
OR
Dispatcher.BeginInvoke(() => { lb.SelectedItem = null; });
Option 2: Create a custom list box class that inherits from ListBox – let’s call it CustomListBox. Override the GetContainerForItemOverride method to return a custom list box item class (CustomListBoxItem) rather than the default ListBoxItem instance. Create a new public event called CustomSelectionChanged which will serve as the replacement for SelectionChanged.
public class CustomListBox : ListBox
{
//fired every time a list box item is clicked
public event SelectionChangedEventHandler CustomSelectionChanged;
protected override DependencyObject GetContainerForItemOverride()
{
CustomListBoxItem item = new CustomListBoxItem(this);
if (base.ItemContainerStyle != null)
{
item.Style = base.ItemContainerStyle;
}
return item;
}
public void OnCustomSelectionChanged(CustomListBoxItem item)
{
List<CustomListBoxItem> addedItems =
new List<CustomListBoxItem>();
addedItems.Add(item);
SelectionChangedEventHandler handler = CustomSelectionChanged;
if (handler != null)
{
handler(this, new SelectionChangedEventArgs(
new List<CustomListBoxItem>(), addedItems));
}
}
}
In CustomListBoxItem, which should inherit from ListBoxItem, create a constructor that takes a CustomListBox instance as a parameter and stores is for later use. Finally, override the OnMouseLeftButtonDown method and fire the CustomSelectionChanged event of the containing CustomListBox.
public class CustomListBoxItem : ListBoxItem
{
CustomListBox _customListBoxContainer;
// Needed to avoid error in case of instantiation in XAML. If
// CustomListBoxItems are added in XAML directly,
// CustomListBox will act like a normal ListBox and only allow
// each item to be selected once.
public CustomListBoxItem()
{ }
public CustomListBoxItem(CustomListBox customListBox)
{
this._customListBoxContainer = customListBox;
}
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
if (this._customListBoxContainer != null)
{
this._customListBoxContainer.OnCustomSelectionChanged(this);
}
}
}
Download example: ResetListBoxExample.zip
11/18/2008 12:13:25 PM (Pacific Standard Time, UTC-08:00)
Shrewd Programming

Tuesday, September 27, 2005
Amusing Exception Message
I was recently working with GDI+ drawing when I found the need to modify a Pen's Width property. I often use the Pens class as a matter of convenience so my first thought was to simply write the following:
Pens.Yellow.Width = 3;
However, that did not work too well as I was greeted with the exception "You may not change this Pen because it does not belong to you." When I read the message I immediately realized that I had made a mistake, but the wording of the exception message also made me laugh a little. It sounds like the Drawing namespace is a little kid that doesn't want me to play with its toys, although in that case it would probably just say "Mine!"

In case you are wondering, the Pens class houses a number of static properties representing a number of colors, including Yellow. The static Yellow property will create a new immutable Pen object with width 1 when you first use it and then store it in a hash table for future use. Future calls to Pens.Yellow will get the same Pen object that was previously stored in the hash table. This is done because GDI Pens are a limited resource that needs to be conserved.
9/27/2005 11:11:15 PM (Pacific Standard Time, UTC-08:00)
Shrewd Programming

Wednesday, July 20, 2005
Funniest .NET languages
What are the funniest .NET language names out there? Here are a few that tickled my funny bone. By the way, I ran them by my wife and she authenticated their funniness. While I do openly poke fun at the names, it is all in good fun. No harm came to the languages used in the making of this posting.
Boo
Common Larceny
Objective Caml
Hotdog
Tachy
TickleSharp
7/20/2005 11:30:01 PM (Pacific Standard Time, UTC-08:00)
Shrewd Programming