RadWindow
and RadComboBox that I am talking about here are both from Telerik(www.telerik.com) Silverlight controls, we use
it quite a lot in our project.
Recently
, I notice an issue when using RadComboBox inside RadWindow , which somehow cause the RadComboBox to open it's dropdown unexpectedly. Obviously it is quite annoying.
Originally
I was suspect it is caused by our program related to the way how we use
RadWindow and RadComboBox, but it turns out it is not ,because I created an
isolated project and I can reproduce the same issue. Just create a UserControl, and then drop a
few RadComboBox in it. Set the
IsEditable=True, OpenDropDownOnFocus = true.
Then use
code to open a RadWindow, Let's call it window1, and set the UserControl we
created above as the content. Inside the
UserControl , provide a button , when click the button , open another
RadWindow, let's call it window 2,
Then leave window 2 open as it
is, and click one of the RadComboBox on the
window 1, you will find out that all the combobox has it's dropdown
open.
it will looks like the following snapshot.
I attach the sample project here.download
I also submit this issue to Telerik with the sample project , they confirm it is an issue, but no good solution yet.
But I work out a workaround that will
collapse the dropdown when it is open without focus.
I use a
behaviour to achieve this, cause behaviour is nice , it can be easily add to
the control without messing up the view's code behind. We are quite strictly
using MVVM. So there is very minimal
code in the view's code behind.
using System.Windows.Interactivity; using Telerik.Windows.Controls; using System.Windows; /// <summary> /// Behavior to close unexpected dropdown behavior /// </summary> public class RadComboBoxCloseUnexpectedDropdownBehavior : Behavior<RadComboBox> { /// <summary> /// Default Constructor. /// </summary> public RadComboBoxCloseUnexpectedDropdownBehavior() { } /// <summary> /// When the behavior get attached into Visual Tree. /// </summary> protected override void OnAttached() { base.OnAttached(); if (null == this.AssociatedObject) return; this.AssociatedObject.DropDownOpened += new SystemEventHandler(AssociatedObject_DropDownOpened); } void AssociatedObject_DropDownOpened(object sender, SystemEventArgs e) { if(!this.AssociatedObject.IsEnabled || !this.AssociatedObject.IsFocused) this.AssociatedObject.IsDropDownOpen = false; } /// <summary> /// Check whether keyboard focus is in this control. /// </summary> /// <param name="element"></param> /// <returns></returns> bool IsKeyboardFocusWithin(UIElement element) { UIElement uiElement = FocusManagerHelper.GetFocusedElement((DependencyObject)element) as UIElement; if (uiElement != null) return ParentOfTypeExtensions.IsAncestorOf((DependencyObject)element, (DependencyObject)uiElement); return false; } /// <summary> /// When behavior get removed /// </summary> protected override void OnDetaching() { this.AssociatedObject.DropDownOpened -= AssociatedObject_DropDownOpened; base.OnDetaching(); } }
In order to use this behavior conveniently in Style, I also create attached property
/// <summary> /// Extensions on RadComboBox. /// </summary> public static class RadComboBoxExtensions { #region CloseDropdown /// <summary> /// Gets the <see cref="CloseUnexpectedDropdownProperty"/> /// </summary> public static readonly DependencyProperty CloseUnexpectedDropdownProperty = DependencyProperty.RegisterAttached( "CloseUnexpectedDropdown", typeof(bool), typeof(RadComboBox), //Note MUST be DepOb to support use in styles new PropertyMetadata(OnCloseUnexpectedDropdownChanged)); /// <summary> /// Sets the DropOnFocus value /// </summary> /// <param name="element">Element</param> /// <param name="value">Value</param> public static void SetCloseUnexpectedDropdown(RadComboBox element, bool value) { element.SetValue(CloseUnexpectedDropdownProperty, value); } /// <summary> /// Gets the DropOnFocus value /// </summary> /// <param name="element">Element</param> /// <returns>Bool</returns> public static bool GetCloseUnexpectedDropdown(RadComboBox element) { return (bool)element.GetValue(CloseUnexpectedDropdownProperty); } static void OnCloseUnexpectedDropdownChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var behaviours = Interaction.GetBehaviors(d); var existing = behaviours.OfType<RadComboBoxCloseUnexpectedDropdownBehavior>().ToList(); if ((e.NewValue is bool) && (bool)e.NewValue) { if (existing.Count <= 0) behaviours.Add(new RadComboBoxCloseUnexpectedDropdownBehavior()); } else { foreach (var item in existing) { behaviours.Remove(item); } } } #endregion }
I didn't dig into telerik's RadWindow source code to see what actually cause this, but I suspect the window is trying to to set the focus appropriately when it get activated,but I hope Telerik can fix this issue appropriately in their future release.