WPF: MouseEnter не работает на нескольких кнопках при нажатии мыши - PullRequest
1 голос
/ 13 января 2011


У меня есть список кнопок-переключателей в wpf, и я хочу, чтобы пользователь мог переключать несколько кнопок, перетаскивая их. Для этого я использовал MouseEnter-Event для каждой кнопки. Это работает, когда я нажимаю кнопку мыши за пределами кнопок и начинаю перетаскивать. Но когда я нажимаю кнопку мыши на кнопке и начинаю перетаскивать, MouseEnter-Event запускается только для первой кнопки, где я нажал кнопку мыши (также не запускаются никакие другие события, такие как mouseover или mousemove).
Вот код:

public void AddButton()
{
    ToggleButton btn = new ToggleButton();
    btn.MouseEnter += VisibilityButton_Enter;
    this.gridButtons.Children.Add(btn);
}

private void VisibilityButton_Enter(object sender, MouseEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed)
    {
        ToggleButton btn = sender as ToggleButton;
        btn.IsChecked = !btn.IsChecked;
    }
}

Я нашел решение использовать «перетаскивание» и событие dragover, но я думаю, что должно быть более простое решение?

Ответы [ 3 ]

1 голос
/ 14 января 2011

Как упоминал Кент, ToggleButton захватывает мышь.Если мы обработаем событие PreviewMouseDown сами, мы сможем предотвратить это.Остальное - просто отслеживание состояния мыши, чтобы мы не щелкали дважды в течение одного пролонгации.Вот поведение, которое вы можете добавить к своей кнопке, чтобы включить повторное нажатие.

Сначала добавьте это пространство имен:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

и соответствующую ссылку на ваш проект.

Тогда XAML выглядит следующим образом (обратите внимание на RollOverBehavior):

<Grid>
    <ItemsControl>
        <ItemsControl.ItemsSource>
            <PointCollection>
                <Point/>
                <Point/>
                <Point/>
                <Point/>
                <Point/>
            </PointCollection>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <ToggleButton Width="25" Height="25">
                    <i:Interaction.Behaviors>
                        <local:RollOverBehavior/>
                    </i:Interaction.Behaviors>
                </ToggleButton>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

и вот само поведение:

public class RollOverBehavior : Behavior<ToggleButton>
{
    bool mouseOver;
    bool clicked;

    protected override void OnAttached()
    {
        AssociatedObject.PreviewMouseLeftButtonDown += (s, e) =>
        {
            AssociatedObject.IsChecked = !AssociatedObject.IsChecked;
            e.Handled = true;
        };
        AssociatedObject.MouseEnter += (s, e) =>
        {
            mouseOver = true;
            clicked = false;
        };
        AssociatedObject.MouseLeave += (s, e) =>
        {
            mouseOver = false;
        };
        AssociatedObject.MouseMove += (s, e) =>
        {
            if (mouseOver && !clicked && e.LeftButton == MouseButtonState.Pressed)
            {
                AssociatedObject.IsChecked = !AssociatedObject.IsChecked;
                clicked = true;
            }
        };
    }
}
1 голос
/ 13 января 2011

Проблема в том, что стандартное поведение ToggleButton заключается в захвате мыши при нажатии левой кнопки мыши.Поскольку мышь захвачена, все события мыши отправляются на первый ToggleButton.

Похоже, что вы хотите сделать, переопределить это поведение по умолчанию, так что мышь не захвачена, но, честно говоря, яне мог точно понять, чего вы пытаетесь достичь.

0 голосов
/ 20 ноября 2018

У меня была такая же проблема с нормальным Buttons.Решение, которое сработало для меня, состоит в том, чтобы установить e.Handled = true в событии PreviewMouseButtonDown (я тоже это реализовал).Похоже, что простым щелчком мыши мыши предыдущее действие не будет полностью обработано, пока кнопка мыши не будет отпущена, поэтому событие MouseEnter не может быть вызвано.

...