С# - как я могу предотвратить прокрутку мыши в моих списках?

У меня есть combobox, и я хочу, чтобы пользователь не прокручивал элементы с помощью мыши.

Есть ли простой способ сделать это?

(С#, VS2008)

Ответ 1

Используйте MouseWheel для вашего ComboBox:

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

Примечание: вам нужно создать событие в коде:

comboBox1.MouseWheel += new MouseEventHandler(comboBox1_MouseWheel);

Ответ 2

Для WPF обработайте событие PreviewMouseWheel.

Также было бы неплохо рассмотреть ComboBox.IsDropDownOpen чтобы пользователь мог по-прежнему использовать прокрутку мыши, если в ComboBox много элементов при расширении 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 при использовании колеса мыши). Если он прокручивается за пределы видимой части comboBox, поле со списком не должно прокручиваться, в противном случае оно должно быть.

Мое решение:

  • Поместите текстовое поле только для чтения вне видимой части экрана. В form_load я поместил строку: hiddenTextbox.left = -100;

  • Установите фокус на это текстовое поле, когда мышь покидает поле со списком с помощью события оставления мыши. В comboBox1_MouseLeave я поместил строку: hiddenTextbox.focus();

  • Обработать событие mouseWheel: From1.MouseWheel + = Form1_MouseWheel;       textBoxHidden.MouseWheel + = Form1_MouseWheel;

Ответ 4

Мой Combobox был помещен в DataGrid [С#, 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>

Таким образом, всякий раз, когда DropDown был закрыт после выбора значения, колесико мыши прокручивало эти элементы комбинированного списка и изменял мой выбор.

В итоге я изменил свой 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();
        }

Таким образом, я просто перемещаю Focus из ComboBox во внешний DataGrid после закрытия соответствующего DropDown, поэтому мне не нужно добавлять какой-либо фиктивный FrameWorkElement