Le Silverlight Control Toolkit comprend un contrôle fort utile pour les applications RIA : l’AutoCompleteBox. Malheureusement, sa propriété SelectedItem est en lecture seule, et ne permet donc pas de faire du Binding dessus. Il existe 2 solutions à ce problème :
1. Télécharger les sources associées au ChangeSet 10371 ou supérieur sur le site CodePlex et recompiler le toolkit
2. Passer par une attached property (seule solution garantissant qu’il n’y ait pas de Breaking Change):
public class AutoCompleteHelper : DependencyObject
{
public static bool GetBound(DependencyObject obj)
{
return (bool)obj.GetValue(BoundProperty);
}
public static void SetBound(DependencyObject obj, bool value)
{
obj.SetValue(BoundProperty, value);
}
// Using a DependencyProperty as the backing store for Bound. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BoundProperty =
DependencyProperty.RegisterAttached("Bound", typeof(bool), typeof(AutoCompleteHelper), new PropertyMetadata(false,
(sender, args) =>
{
var box = sender as AutoCompleteBox;
if ((bool)args.NewValue)
box.SelectionChanged += box_SelectionChanged;
else
box.SelectionChanged -= box_SelectionChanged;
}));
static void box_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var box = sender as AutoCompleteBox;
SetSelectedItem(box, box.SelectedItem);
}
public static object GetSelectedItem(AutoCompleteBox obj)
{
return (object)obj.GetValue(SelectedItemProperty);
}
public static void SetSelectedItem(AutoCompleteBox obj, object value)
{
obj.SetValue(SelectedItemProperty, value);
}
// Using a DependencyProperty as the backing store for SelectedItem. This enables animation, styling, binding, etc...
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.RegisterAttached("SelectedItem", typeof(object), typeof(AutoCompleteHelper), new PropertyMetadata(null,
(sender, args) =>
{
var box = sender as AutoCompleteBox;
var txt = string.Empty;
if (args.NewValue != null)
txt = args.NewValue.ToString();
box.Text = txt;
SetBound(box, true);
}));
}
Ensuite, dans le xaml il suffira de faire:
<tk:AutoCompleteBox ItemsSource="{Binding ItemsSource}"
c:AutoCompleteHelper.SelectedItem="{Binding TheSelectedItem, Mode=TwoWay}"
c:AutoCompleteHelper.Bound="true" />
Enjoy !