我有一個ToggleButton我已經將模板設定為一個新的ControlTemplate我有一個我已經添加到這個的行為ToggleButton。
<ControlTemplate TargetType="ToggleButton" x:Key="IconToggleButton">
<Border
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="15 0 0 15"
Height="{TemplateBinding Height}"
MinHeight="{TemplateBinding MinHeight}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
Width="{TemplateBinding Width}">
<Grid>
<TextBlock
FontFamily="{TemplateBinding FontFamily}"
Foreground="{StaticResource White}"
HorizontalAlignment="Center"
Text="{TemplateBinding Content}"
VerticalAlignment="Center" />
</Grid>
</Border>
</ControlTemplate>
<ToggleButton
Background="{StaticResource LightGray}"
BorderBrush="{StaticResource LightGray}"
BorderThickness="1"
Content="{x:Static constants:FontAwesomeIcons.Bars}"
FontFamily="{StaticResource FontAwesomeSolid}"
FontSize="19"
HorizontalAlignment="Center"
MinHeight="35"
MouseLeftButtonDown="UIElement_OnMouseDown"
Template="{StaticResource IconToggleButton}"
VerticalAlignment="Top"
Width="38"
x:Name="ToggleButton">
<b:Interaction.Behaviors>
<b:MouseDragElementBehavior ConstrainToParentBounds="True" />
</b:Interaction.Behaviors>
</ToggleButton>
private void UIElement_OnMouseDown(object sender, MouseButtonEventArgs e)
{
Debug.WriteLine(sender.GetType().Name);
e.Handled = false;
}
我的問題是因為ToggleButton正在處理事件該行為實際上永遠不會觸發。

所以,關于我的問題:我怎樣才能獲得捕捉這個MouseLeftButtonDown事件的行為。
uj5u.com熱心網友回復:
確實處理滑鼠輸入事件的MouseDragElementBehavior冒泡版本。并且這些事件被標記為由 處理,Button因為這些事件被替換為Button.Click事件。這意味著UIElement.MouseLeftButtonDown和UIElement.MouseDown事件被 Button 吞沒。只有那些事件的隧道版本被允許遍歷。
要借助MouseDragElementBehaviorfor aButton或任何將冒泡滑鼠事件標記為已處理的控制元件啟用拖動,您必須手動控制此行為。
為此,UIElement.PreviewMouseLeftButtonDown在可拖動元素上為隧道事件注冊一個處理程式:
<ToggleButton PreviewMouseLeftButtonDown="OnDraggableElementLeftButtonDown">
<b:Interaction.Behaviors>
<b:MouseDragElementBehavior ConstrainToParentBounds="True" />
</b:Interaction.Behaviors>
</ToggleButton>
private Point DragStartPosition { get; set; }
private void OnDraggableElementLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var draggableElement = sender as UIElement;
this.DragStartPosition = e.GetPosition(this);
draggableElement.PreviewMouseMove = OnDraggingElementMouseMove;
draggableElement.PreviewMouseLeftButtonUp = OnDraggedElementLeftButtonUp;
}
protected void OnDraggingElementMouseMove(object sender, MouseEventArgs e)
{
var draggingElement = sender as UIElement;
Microsoft.Xaml.Behaviors.Layout.MouseDragElementBehavior dragMoveBehavior = Microsoft.Xaml.Behaviors.Interaction.GetBehaviors(draggingElement)
.OfType<Microsoft.Xaml.Behaviors.Layout.MouseDragElementBehavior>()
.First();
Point initialDraggableElementPosition = draggingElement.TranslatePoint(new Point(0, 0), this);
if (double.IsNaN(dragMoveBehavior.X))
{
dragMoveBehavior.X = initialDraggableElementPosition.X;
}
if (double.IsNaN(dragMoveBehavior.Y))
{
dragMoveBehavior.Y = initialDraggableElementPosition.Y;
}
Point mousePosition = e.GetPosition(this);
dragMoveBehavior.X = mousePosition.X - this.DragStartPosition.X;
dragMoveBehavior.Y = mousePosition.Y - this.DragStartPosition.Y;
this.DragStartPosition = new Point(mousePosition.X, mousePosition.Y);
}
private void OnDraggedElementLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var draggedElement = sender as UIElement;
draggedElement.PreviewMouseMove -= OnDraggingElementMouseMove;
draggedElement.PreviewMouseLeftButtonUp -= OnDraggedElementLeftButtonUp;
}
為了方便起見,您可能希望將 包裝MouseDragElementBehavior到自定義Behavior或附加行為中。然后,您可以使用此行為來啟用元素拖動。
這樣,您不再需要關心元素是否將冒泡滑鼠事件標記為已處理。此自定義行為將使用上述代碼
在內部將拖動操作委托給包裝:MouseDragElementBehavior
<ToggleButton local:MyMouseDragElementBehavior.IsEnabled="True"
local:MyMouseDragElementBehavior.ConstrainToParentBounds="True" />
public class MyMouseDragElementBehavior : DependencyObject
{
public static bool GetIsEnabled(DependencyObject attachingElement) => (bool)attachingElement.GetValue(IsEnabledProperty);
public static void SetIsEnabled(DependencyObject attachingElement, bool value) => attachingElement.SetValue(IsEnabledProperty, value);
public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached(
"IsEnabled",
typeof(bool),
typeof(MyMouseDragElementBehavior),
new PropertyMetadata(default(bool), OnIsEnabledChanged));
public static bool GetConstrainToParentBounds(DependencyObject attachingElement) => (bool)attachingElement.GetValue(ConstrainToParentBoundsProperty);
public static void SetConstrainToParentBounds(DependencyObject attachingElement, bool value) => attachingElement.SetValue(ConstrainToParentBoundsProperty, value);
public static readonly DependencyProperty ConstrainToParentBoundsProperty = DependencyProperty.RegisterAttached(
"ConstrainToParentBounds",
typeof(bool),
typeof(MyMouseDragElementBehavior),
new PropertyMetadata(default(bool), OnConstrainToParentBoundsChanged));
private static Dictionary<DependencyObject, MouseDragElementBehavior> BehaviorTable { get; } = new Dictionary<DependencyObject, MouseDragElementBehavior>();
private static Dictionary<DependencyObject, Window> RootVisualTable { get; } = new Dictionary<DependencyObject, Window>();
private static Point DragStartPosition { get; set; }
private static void OnIsEnabledChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
{
if (attachingElement is not UIElement attachingUiElement)
{
return;
}
if ((bool)e.NewValue)
{
var isConstrainToParentBoundsEnabled = GetConstrainToParentBounds(attachingUiElement);
var dragBehavior = new MouseDragElementBehavior() { ConstrainToParentBounds = isConstrainToParentBoundsEnabled };
BehaviorTable.Add(attachingUiElement, dragBehavior);
dragBehavior.Attach(attachingUiElement);
Window rootVisualOfAttachingElement = Window.GetWindow(attachingElement);
RootVisualTable.Add(attachingUiElement, rootVisualOfAttachingElement);
attachingUiElement.PreviewMouseLeftButtonDown = OnDraggableElementLeftButtonDown;
}
else
{
if (BehaviorTable.TryGetValue(attachingUiElement, out MouseDragElementBehavior dragBehavior))
{
dragBehavior.Detach();
BehaviorTable.Remove(attachingUiElement);
}
RootVisualTable.Remove(attachingUiElement);
}
}
private static void OnConstrainToParentBoundsChanged(DependencyObject attachingElement, DependencyPropertyChangedEventArgs e)
{
if (!BehaviorTable.TryGetValue(attachingElement, out MouseDragElementBehavior dragMoveBehavior))
{
return;
}
dragMoveBehavior.ConstrainToParentBounds = (bool)e.NewValue;
}
private static void OnDraggableElementLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var draggableElement = sender as UIElement;
if (!RootVisualTable.TryGetValue(draggableElement, out Window rootVisualOfDraggableElement))
{
return;
}
DragStartPosition = e.GetPosition(rootVisualOfDraggableElement);
draggableElement.PreviewMouseMove = OnDraggingElementMouseMove;
draggableElement.PreviewMouseLeftButtonUp = OnDraggingElementLeftButtonUp;
}
private static void OnDraggingElementLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var draggedElement = sender as UIElement;
draggedElement.PreviewMouseMove -= OnDraggingElementMouseMove;
draggedElement.PreviewMouseLeftButtonUp -= OnDraggingElementLeftButtonUp;
}
private static void OnDraggingElementMouseMove(object sender, MouseEventArgs e)
{
var draggingElement = sender as UIElement;
if (!BehaviorTable.TryGetValue(draggingElement, out MouseDragElementBehavior dragMoveBehavior)
|| !RootVisualTable.TryGetValue(draggingElement, out Window rootVisualOfDraggingElement)
{
return;
}
Point initialDraggableElementPosition = draggingElement.TranslatePoint(new Point(0, 0), rootVisualOfDraggingElement);
if (double.IsNaN(dragMoveBehavior.X))
{
dragMoveBehavior.X = initialDraggableElementPosition.X;
}
if (double.IsNaN(dragMoveBehavior.Y))
{
dragMoveBehavior.Y = initialDraggableElementPosition.Y;
}
Point mousePosition = e.GetPosition(rootVisualOfDraggingElement);
dragMoveBehavior.X = mousePosition.X - DragStartPosition.X;
dragMoveBehavior.Y = mousePosition.Y - DragStartPosition.Y;
DragStartPosition = new Point(mousePosition.X, mousePosition.Y);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/511403.html
標籤:C#wpfxml
