I need to prevent scrolling through the ComboBox
selected items when the mouse hovers over the closed ComboBox
.
I have seen this done using code behind (e.g. this), but I need to do it without code behind, in a way that could be easily reused throughout the project.
For example, elsewhere in our project we use IValueConverter to do make a StaticResource
that can easily be added where required.
Is there a way to make a StaticResource
for the ComboBox
that could prevent scrolling?
Is there an interface like IValueConveter
that could be used in place of the EventSetter
Handler
?
but I need to do it without code behind, in a way that could be easily reused throughout the project.
So wrap the code-behind functionality in an attached behaviour:
public static class NoScrollingBehaviour
{
public static bool GetEnabled(ComboBox comboBox) =>
(bool)comboBox.GetValue(EnabledProperty);
public static void SetEnabled(ComboBox comboBox, bool value) =>
comboBox.SetValue(EnabledProperty, value);
public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached(
"Enabled",
typeof(bool),
typeof(NoScrollingBehaviour),
new UIPropertyMetadata(false, OnEnabledChanged));
private static void OnEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ComboBox comboBox = (ComboBox)d;
if (GetEnabled(comboBox))
{
FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.AddHandler(FrameworkElement.RequestBringIntoViewEvent, new RequestBringIntoViewEventHandler(OnRequestBringIntoView));
comboBox.ItemsPanel = new ItemsPanelTemplate() { VisualTree = stackPanel };
}
}
private static void OnRequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
if (Keyboard.IsKeyDown(Key.Down) || Keyboard.IsKeyDown(Key.Up))
return;
e.Handled = true;
}
}
You can then easily reuse it for different ComboBox
elements:
<ComboBox local:NoScrollingBehaviour.Enabled="true" />