using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
namespace Ravi.UI.Silverlight
{
///
///
public class ComboBox : System.Windows.Controls.ComboBox
{
#region Constructor
///
///
public ComboBox()
{
this.Loaded += new RoutedEventHandler(ComboBox_Loaded);
this.SelectionChanged += new SelectionChangedEventHandler(ComboBox_SelectionChanged);
}
#endregion
#region Events
///
///
///
///
void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
SetSelectionFromValue();
}
private object _selection;
void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
_selection = e.AddedItems[0];
SelectedValue = GetMemberValue(_selection);
}
else
{
_selection = null;
SelectedValue = null;
}
}
#endregion
#region Dependency Properties
public static DependencyProperty SelectedValueProperty = DependencyProperty.Register(“SelectedValue”,
typeof(object),
typeof(
Keller.UI.Silverlight.
ComboBox),
new PropertyMetadata(
(o, e) =>
((ComboBox)o).
SetSelectionFromValue
()));
public static DependencyProperty ValueMemberPathProperty = DependencyProperty.Register(“ValueMemberPath”,
typeof(string),
typeof(
Keller.UI.Silverlight
.ComboBox), null);
#endregion
#region Properties
public string ValueMemberPath
{
get
{
return ((string)(base.GetValue(ComboBox.ValueMemberPathProperty)));
}
set
{
base.SetValue(ComboBox.ValueMemberPathProperty, value);
}
}
public object SelectedValue
{
get
{
return ((object)(base.GetValue(ComboBox.SelectedValueProperty)));
}
set
{
base.SetValue(ComboBox.SelectedValueProperty, value);
}
}
#endregion
#region Private Methods
private object GetMemberValue(object item)
{
return item.GetType().GetProperty(ValueMemberPath).GetValue(item, null);
}
private void SetSelectionFromValue()
{
var value = SelectedValue;
if (Items.Count > 0 && value != null)
{
var sel = (from item in Items
where GetMemberValue(item) != null && GetMemberValue(item).Equals(value)
select item).SingleOrDefault();
_selection = sel;
SelectedItem = sel;
}
}
#endregion
#region Overridden methods
protected override void OnItemsChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
SetSelectionFromValue();
}
#endregion
#region KeyBoard Interactivity
private ScrollViewer _scrollViewer;
public override void OnApplyTemplate()
{
_scrollViewer = this.GetTemplateChild(“ScrollViewer”) as ScrollViewer;
if (_scrollViewer != null)
_scrollViewer.SetIsMouseWheelScrollingEnabled(true);
_scrollViewer.KeyDown += new KeyEventHandler(_scrollViewer_KeyDown);
this.KeyDown += new KeyEventHandler(_scrollViewer_KeyDown);
base.OnApplyTemplate();
}
private void _scrollViewer_KeyDown(object sender, KeyEventArgs e)
{
DoKeyDown(sender, e);
}
///
///
public string SelectionMemberPath { get; set; }
public void DoKeyDown(object sender, KeyEventArgs e)
{
// Create a list of strings and indexes
int index = 0;
IEnumerable
var path = SelectionMemberPath ??
this.DisplayMemberPath;
var evaluator = new BindingEvaluator();
if (path != null)
{
list = this.Items.OfType
BindingOperations.SetBinding(evaluator,
BindingEvaluator.TargetProperty, binding);
var value = evaluator.Target;
return new Item
{
Index = index++,
Text = Convert.ToString(value)
};
});
}
else
{
list = this.Items.OfType
.Select(item => new Item
{
Index = index++,
Text = Convert.ToString(item.Content)
});
}
// Sort the list starting at next selectedIndex to the end and
// then from the beginning
list = list.OrderBy(item => item.Index <=
this.SelectedIndex ?
item.Index + this.Items.Count : item.Index);
// Find first starting with
var text = e.Key.ToString();
var first = list.FirstOrDefault(item => item.Text.StartsWith(text,
StringComparison.InvariantCultureIgnoreCase));
if (first != null)
{
// found
this.SelectedIndex = first.Index;
}
}
///
///
private class Item
{
public int Index;
public string Text;
}
///
///
private class BindingEvaluator : FrameworkElement
{
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register(
“Target”,
typeof(object),
typeof(BindingEvaluator), null);
public object Target
{
get { return GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
}
}
#endregion
}
}






