【问题标题】:C# - how do I prevent mousewheel-scrolling in my combobox?C# - 如何防止我的组合框中的鼠标滚轮滚动?
【发布时间】:2010-12-25 09:01:12
【问题描述】:

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

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

(C#,VS2008)

【问题讨论】:

    标签: c# combobox mousewheel


    【解决方案1】:

    为您的 ComboBox 使用 MouseWheel 事件:

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

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

    comboBox1.MouseWheel += new MouseEventHandler(comboBox1_MouseWheel);
    

    【讨论】:

    • 完美运行,谢谢!旁注:如果您希望在下拉 ComboBox 时仍然应用滚动,只需添加以下行:“ComboBox control = (ComboBox)sender;”和 "((HandledMouseEventArgs)e).Handled = true" 行之前的 "if (!control.DroppedDown)"。
    • 这目前不适用于 Mono。 bugzilla.xamarin.com/show_bug.cgi?id=25201
    • 我知道这是旧版本,但我喜欢在表单构造函数中InitializeComponent(); 之后的这个版本:comboBox1.MouseWheel += (o, e) => ((HandledMouseEventArgs)e).Handled = true;
    • 此技术也适用于 WPF 中的组合框,但在事件处理程序中使用参数 object sender, System.Windows.Input.MouseWheelEventArgs e,您不必将 e 强制转换为 HandledMouseEventArgs
    • 只是想指出,这也适用于 NumericUpDown 控件。
    【解决方案2】:

    对于 WPF,请处理 PreviewMouseWheel 事件。

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

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

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

    App.xaml

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

    App.xaml.cs

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

    【讨论】:

      【解决方案3】:

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

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

      我的解决方案:

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

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

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

      【讨论】:

        【解决方案4】:

        我的组合框被放置在 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>
        

        因此,只要在选择值后关闭下拉菜单,鼠标滚轮就会滚动该组合框的项目并修改我的选择。

        我最终将我的 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>
        

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

                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();
                }
        

        通过这种方式,我只是在关闭其相应的下拉菜单后将焦点从组合框移到外部数据网格,所以我不需要添加任何虚拟 FrameWorkElement

        【讨论】:

          猜你喜欢
          • 2014-02-11
          • 2022-11-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-06
          • 1970-01-01
          • 2013-11-30
          相关资源
          最近更新 更多