C# - 如何防止鼠标滚轮在我的组合框中滚动?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1882993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 21:38:00  来源:igfitidea点击:

C# - how do I prevent mousewheel-scrolling in my combobox?

c#comboboxmousewheel

提问by Pygmy

I have a combobox and I want to prevent the user from scrolling through the items with the mousewheel.

我有一个组合框,我想阻止用户使用鼠标滚轮滚动项目。

Is there an easy way to do that?

有没有简单的方法来做到这一点?

(C#, VS2008)

(C#, VS2008)

回答by Jay Riggs

Use the MouseWheelevent for your ComboBox:

为您的 ComboBox使用MouseWheel事件:

void comboBox1_MouseWheel(object sender, MouseEventArgs e) {
    ((HandledMouseEventArgs)e).Handled = true;
}

Note: you'll have to create event in code:

注意:您必须在代码中创建事件:

comboBox1.MouseWheel += new MouseEventHandler(comboBox1_MouseWheel);

回答by Eduard

I use another solution that also works on Mono.

我使用另一种也适用于 Mono 的解决方案。

Goal is to prevent accidentally scrolling (that is when the user is not looking at the comboBox when using the mouse wheel). If he / she scroll outside the visible portion of comboBox , the combo box should not scroll, otherwise it should.

目标是防止意外滚动(即用户在使用鼠标滚轮时未查看组合框时)。如果他/她滚动到 comboBox 的可见部分之外,则组合框不应滚动,否则应该滚动。

My solution:

我的解决方案:

  • Place a read only text box outside the visible portion of the screen. In form_load I placed the line: hiddenTextbox.left = -100 ;

  • Set the focus to this text box when the mouse leaves the combo box using mouse leave event. In comboBox1_MouseLeave I placed the line: hiddenTextbox.focus();

  • Handle mouseWheel event: From1.MouseWheel += Form1_MouseWheel; textBoxHidden.MouseWheel += Form1_MouseWheel;

  • 在屏幕可见部分之外放置一个只读文本框。在 form_load 我放置了一行: hiddenTextbox.left = -100 ;

  • 当鼠标使用鼠标离开事件离开组合框时,将焦点设置到此文本框。在 comboBox1_MouseLeave 中,我放置了一行: hiddenTextbox.focus();

  • 处理 mouseWheel 事件:From1.MouseWheel += Form1_MouseWheel; textBoxHidden.MouseWheel += Form1_MouseWheel;

回答by Jan Paolo Go

For WPF, handle the PreviewMouseWheelevent instead.

对于 WPF,请PreviewMouseWheel改为处理事件。

It would also be a good idea to consider ComboBox.IsDropDownOpenso the user can still use mouse scroll if there are a lot of items in the selection when the ComboBoxis expanded.

ComboBox.IsDropDownOpen如果在ComboBox展开时选择中有很多项目,那么考虑这样用户仍然可以使用鼠标滚动也是一个好主意。

Another thing is to apply the same behavior across the whole application.

另一件事是在整个应用程序中应用相同的行为。

I usually do all the above using the following code:

我通常使用以下代码完成上述所有操作:

App.xaml

应用程序.xaml

<Application.Resources>
    <Style TargetType="ComboBox">
        <EventSetter Event="PreviewMouseWheel" Handler="ComboBox_PreviewMouseWheel" />
    </Style>
</Application.Resources>

App.xaml.cs

应用程序.xaml.cs

private void ComboBox_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
    e.Handled = !((System.Windows.Controls.ComboBox)sender).IsDropDownOpen;
}

回答by Guido De Vecchi

My Combobox's were placed inside a DataGrid [C#, WPF XAML] just like this:

我的组合框被放置在一个 DataGrid [C#, WPF XAML] 中,就像这样:

    <DataGrid x:Name="dgvFieldsMapping" Grid.Row="1" ItemsSource="{Binding}">
        <DataGrid.Columns>
            ...
            <DataGridTemplateColumn Width="*" Header="Destination Field" >
                <DataGridTemplateColumn.CellTemplate >
                    <DataTemplate >
                        <ComboBox ItemsSource="{Binding Source={StaticResource CustomerDbFields}}" SelectedValue="{Binding destinationField, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            ...
        </DataGrid.Columns>
    </DataGrid>

So whenever a DropDown was closed after selecting a Value, the Mousewheel would scroll that Combobox's Items and modify my Selection.

因此,无论何时在选择值后关闭 DropDown,鼠标滚轮都会滚动该组合框的项目并修改我的选择。

I ended up modifying my XAML to look like this:

我最终将 XAML 修改为如下所示:

    <DataGrid x:Name="dgvFieldsMapping" Grid.Row="1" ItemsSource="{Binding}">
        <DataGrid.Resources>
            <Style x:Key="dgvComboBox_Loaded" TargetType="ComboBox">
                <EventSetter Event="Loaded" Handler="dgvCombobox_Loaded" />
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            ...
            <DataGridTemplateColumn Width="*" Header="Destination Field" >
                <DataGridTemplateColumn.CellTemplate >
                    <DataTemplate >
                        <ComboBox Style="{StaticResource dgvComboBox_Loaded}" ItemsSource="{Binding Source={StaticResource CustomerDbFields}}" SelectedValue="{Binding destinationField, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ></ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            ...
        </DataGrid.Columns>
    </DataGrid>

And adding these lines in codebehind

并在代码隐藏中添加这些行

        public void dgvCombobox_Loaded(Object sender, RoutedEventArgs e)
        {
            ((ComboBox)sender).DropDownClosed -= ComboBox_OnDropDownClosed;
            ((ComboBox)sender).DropDownClosed += new System.EventHandler(ComboBox_OnDropDownClosed);
        }

        void ComboBox_OnDropDownClosed(object sender, System.EventArgs e)
        {
            dgvFieldsMapping.Focus();
        }

In this way I just move the Focus away from the ComboBox to the outer DataGrid after closing its corresponding DropDown, so I don't need to add any dummy FrameWorkElement

通过这种方式,我只需在关闭其相应的 DropDown 后将焦点从 ComboBox 移到外部 DataGrid,因此我不需要添加任何虚拟 FrameWorkElement