我在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事件的解决方案,但我认为必须有一个更简单的解决方案?
答案 0 :(得分:1)
问题是ToggleButton
的默认行为是在单击鼠标左键时捕获鼠标。由于捕获了鼠标,因此所有鼠标事件都将发送到第一个ToggleButton
。
听起来你想要做的就是覆盖这个默认行为,以便不捕获鼠标,但说实话,我真的无法完全按照你想要实现的目标。
答案 1 :(得分:1)
正如肯特所说,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;
}
};
}
}
答案 2 :(得分:0)
我在普通Buttons
上遇到了同样的问题。对我有用的解决方案是在e.Handled = true
事件中设置PreviewMouseButtonDown
(我也实现了这一点)。看来,仅通过用鼠标单击才能完全释放之前的操作,直到释放鼠标按钮为止,因此MouseEnter
事件无法引发。