WPF StackPanel 와 클릭하고 DoubleClick
-
10-07-2019 - |
문제
내가 필요할 수 있 처리 더블 클릭 고 한 번의 클릭 이벤트 WPF StackPanel.그러나 같은 것은 없으로 StackPanel 의 DoubleClick 이벤트입니다.내가 하고 싶은 2 가지 작업에서 이러한 2 하십시오.
어떤 아이디어는 어떻게 해야 할까요?
감사
해결책
가장 좋은 방법은 자신의 오른쪽 마우스 버튼을 처리기와 시간 제한-이벤트 발생한 제한 시간 동안,다음 화재의 doubleclick 메시지,그렇지 않으면 전화를 클릭 한 번으로 처리기입니다.여기에 몇 가지 예제 코드(편집: 원래 발견 기):
/// <summary>
/// For double clicks
/// </summary>
public class MouseClickManager {
private event MouseButtonEventHandler _click;
private event MouseButtonEventHandler _doubleClick;
public event MouseButtonEventHandler Click {
add { _click += value; }
remove { _click -= value; }
}
public event MouseButtonEventHandler DoubleClick {
add { _doubleClick += value; }
remove { _doubleClick -= value; }
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="MouseClickManager"/> is clicked.
/// </summary>
/// <value><c>true</c> if clicked; otherwise, <c>false</c>.</value>
private bool Clicked { get; set; }
/// <summary>
/// Gets or sets the timeout.
/// </summary>
/// <value>The timeout.</value>
public int DoubleClickTimeout { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="MouseClickManager"/> class.
/// </summary>
/// <param name="control">The control.</param>
public MouseClickManager(int doubleClickTimeout) {
this.Clicked = false;
this.DoubleClickTimeout = doubleClickTimeout;
}
/// <summary>
/// Handles the click.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
public void HandleClick(object sender, MouseButtonEventArgs e) {
lock (this) {
if (this.Clicked) {
this.Clicked = false;
OnDoubleClick(sender, e);
}
else {
this.Clicked = true;
ParameterizedThreadStart threadStart = new ParameterizedThreadStart(ResetThread);
Thread thread = new Thread(threadStart);
thread.Start(e);
}
}
}
/// <summary>
/// Resets the thread.
/// </summary>
/// <param name="state">The state.</param>
private void ResetThread(object state) {
Thread.Sleep(this.DoubleClickTimeout);
lock (this) {
if (this.Clicked) {
this.Clicked = false;
OnClick(this, (MouseButtonEventArgs)state);
}
}
}
/// <summary>
/// Called when [click].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
private void OnClick(object sender, MouseButtonEventArgs e) {
if (_click != null) {
if (sender is Control) {
(sender as Control).Dispatcher.BeginInvoke(_click, sender, e);
}
}
}
/// <summary>
/// Called when [double click].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param>
private void OnDoubleClick(object sender, MouseButtonEventArgs e) {
if (_doubleClick != null) {
_doubleClick(sender, e);
}
}
}
그런 다음,컨트롤 받고 싶 이벤트:
MouseClickManager fMouseManager = new MouseClickManager(200);
fMouseManager.Click += new MouseButtonEventHandler(YourControl_Click);
fMouseManager.DoubleClick += new MouseButtonEventHandler(YourControl_DoubleClick);
다른 팁
<StackPanel MouseDown="StackPanel_MouseDown">
<!--stackpanel content-->
<TextBlock>Hello</TextBlock>
</StackPanel>
그런 다음 이벤트에서 처리기:
private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.ClickCount >= 2)
{
string hello; //only hit here on double click
}
}
작업해야 합니다.참고는 하나의 클릭하면서 StackPanel 을 칠 것 이벤트(하지만 실패하는 경우 체크인)
...합니다.@MoominTroll 의 솔루션이 완벽하게 허용됩니다.또 다른 옵션은 감싸 스택에서 패널 컨텐츠 제어를 지원하는 두 번 이벤트를 클릭합니다.
<ContentControl MouseDoubleClick="DoubleClickHandler" >
<StackPanel>
</StackPanel>
</ContentControl>
또 다른 옵션은 추가 MouseBinding 을 InputBindings 에 StackElement 를 추가 CommandBinding 는 의해 활성화된 MouseBinding.전체에서 이것은 더 나은 연습보다 이벤트 기반의 메커니즘을 피할 수 있기 때문에 메모리 누출로 인해 발생하는 문제 강한 참조가 있습니다.그것은 또한 제공을 위한 분리를 명령의 논리에서 표현입니다.
그는 말했다,그것의 똑바로 앞으로 첨부하기 이벤트는 훌륭한 바로 가기가 있습니다.
고 그것은 말할 것도 없고,당신의 stackpanel 배경에는 최소한 투명한 또는 손해를 입지 않도록 충분히 마우스로 클릭 hit 테스트를 클릭할 때"배경".Null 배경 건너뛰에 의해 충돌 감지합니다.
나는 비슷한 문제가 있었(응답을 클릭 한 번 이벤트 및 당 추가적인 작업의 경우 더블릭 이벤트).나는이 문제를 해결에 이 방법:
1)정의하고 선포하는 일부 정수를 개최하는 마지막 클릭 timestamp
int lastClickTimestamp;
2)Window_Loaded 초기화 방법 이전에 이 변수 선언으로 일부 숫자보다 큰 200
lastClickTimestamp = 1000;
3)추가로 마우스 단추 핸들러를 당신의 스택이 패널
stackPanel.MouseLeftButtonUp += new MouseButtonEventHandler(stackPanel_MouseLeftButtonUp);
4)다음과 같은 방법으로 추가
void stackPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (e.Timestamp - lastClickTimeStamp < 200)
{
//double click
}
lastClickTimeStamp = e.Timestamp;
//single click
}
이 코드는 쓸모 없는 필요하신 경우에는 별도로 감지 하나의 클릭 및 더블 클릭의 이벤트입니다.는 상황을 소개하고 좀 더 복잡,하지만 분명히 해결할 수 있습니다.
완전한 답변을 사용하여 WPF DispatcherTimer
.우리가 만든 타이머에 수요와 그것을 분리 할 경우를 방지하기 위해 자원의 막힘.
C#:
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
public partial class MainWindow : Window
{
DispatcherTimer dt;
bool clear_timer()
{
if (dt == null)
return false;
dt.Tick -= _single_click;
dt = null;
return true;
}
private void _click(Object sender, MouseButtonEventArgs e)
{
if (clear_timer())
Debug.Print("double click");
else
dt = new DispatcherTimer(
TimeSpan.FromMilliseconds(GetDoubleClickTime()),
DispatcherPriority.Normal,
_single_click,
Dispatcher);
}
void _single_click(Object sender, EventArgs e)
{
clear_timer();
Debug.Print("single click");
}
public MainWindow() { InitializeComponent(); }
[DllImport("user32.dll")]
static extern uint GetDoubleClickTime();
};
XAML:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Orientation="Horizontal"
Background="AliceBlue"
Width="100"
Height="100"
MouseLeftButtonDown="_click" />
</Window>
가 있는 간편한 솔루션을니다.
에 StackPanel 의 이벤트 PreviewMouseLeftDown(예를 들어),는지 확인할 수 있습 MouseButtonEventArgs.ClickCount 속성 값은 2 입니다.1=단 한 번의 클릭 2=더블 클릭