이제 WPF로 바꿔보세요 (15)
15778 단어 VisualStudioVisualBasicC#WPF
DragMove의 문제
DragMove 편리합니다만 하고 싶다고 생각하고 있는 Screen의 인연에의 스냅이 잘 되지 않아.
하고 싶은 것은 일정 이상 가장자리에 가까워지면 가장자리에 흡착시킨다는 것.
VB의 경우
①드래그의 개시시에 윈도우의 TOP·LEFT를 취해 둔다
② 드래그 중에는 왼쪽 버튼을 누르고 있는 동안 마진의 사이즈를 가산하여 커서 포지션을 산출하고, 윈도우를 산출 좌표에 로케이트 한다는 같은 구현으로 OK였습니다. VB↓
Private Sub DragStart()
Dragging = True
offsetPos.X = MousePosition.X - Left
offsetPos.Y = MousePosition.Y - Top
End Sub
Private Sub Drag(e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
If Dragging = True Then
Me.Location = GetPos(offsetPos)
End If
End If
End Sub
Private Sub DragEnd()
If Dragging = True Then
Me.Location = GetPos(offsetPos)
End If
Dragging = False
End Sub
Private Function GetPos(aPos) As Point
GetPos.Y = MousePosition.Y - aPos.Y
GetPos.X = MousePosition.X - aPos.X
'スクリーンフレームへの吸着
If GetPos.Y < marginsize Then GetPos.Y = 0
If GetPos.X < marginsize Then GetPos.X = 0
If (GetPos.Y + Height + marginsize) > h Then GetPos.Y = h - Height
If (GetPos.X + Width + marginsize) > w Then GetPos.X = w - Width
End Function
처음 DragMove를 사용하지 않고 그대로 C#으로 바꿔 보았습니다만, 빠른 드래그 조작에 화면이 붙어 이것이 아닙니다. 에서 화면에서 커서 아웃하면, 거기에서 제어가 손실됩니다.
아무래도 사용할 수 있을 것 같지 않기 때문에, 역시 반응이 좋은 DragMove를 사용해, 이하와 같은 순서로 변경.
드래그 중인 ChangeLocation 이벤트 내에서 윈도우의 상하 좌우 좌표가 Screen의 Working 영역에 스냅 마진을 가산·감산한 범위내가 되었을 경우, 스냅 후의 지정값으로 윈도우 위치를 변경.
C#에서는 이런 느낌으로 ↓ (G.SR에는 화면 해상도가 들어 있습니다. 1.25 같은)
private void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ButtonState != MouseButtonState.Pressed) return;
DragMove(); //ここからDragMove
}
private void Window_MouseUp(object sender, MouseButtonEventArgs e)
{
//Draggingの終了
if (G.isDragging == true) G.isDragging = false;
}
private void Window_LocationChanged(object sender, EventArgs e)
{
if(G.isTransing == false) //画面TransitionによるLocationChangedは無視する
{
//ドラッグ中の場合はG.isDragging = trueにしておくことで最初のクリックイベントを回避
if (Mouse.LeftButton == MouseButtonState.Pressed) G.isDragging = true;
else G.isDragging = false;
//スクリーン縁への吸着
var NewPos = GetPos();
var hwnd = new WindowInteropHelper(this).Handle;
NativeMethods.SetWindowPos(hwnd, IntPtr.Zero, (int)Math.Round(NewPos.X), (int)Math.Round(NewPos.Y),
(int)Math.Round(Width * G.SR), (int)Math.Round(Height * G.SR), Consts.SWP_NOZORDER);
}
}
private Point GetPos()
{
var NewWindowPos = new Point();
NewWindowPos.X = this.Left * G.SR;
NewWindowPos.Y = this.Top * G.SR;
if (NewWindowPos.X < G.marginsize) NewWindowPos.X = 0; //左辺への吸着
if (NewWindowPos.Y < G.marginsize) NewWindowPos.Y = 0; //上辺への吸着
if (NewWindowPos.X + (Width * G.SR) + G.marginsize > G.SW) NewWindowPos.X = G.SW - (Width * G.SR); //右辺への吸着
if (NewWindowPos.Y + (Height * G.SR) + G.marginsize > G.SH) NewWindowPos.Y = G.SH - (Height * G.SR); //底辺への吸着
return NewWindowPos;
}
결과적으로 가장자리에 대한 스냅은 성공했지만 테두리 밖으로 드래그하면 계속 깜박임이 발생합니다. 본 느낌, DragMove에 의해 일단 테두리 밖에 묘화해, 그 뒤 LocationChanged내의 SetWindowPos로 테두리내에 묘화하고 있는 바람.
해결책 생각하지 않기 때문에, 이대로 가는 것에.
Reference
이 문제에 관하여(이제 WPF로 바꿔보세요 (15)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/Insetrect/items/04cd8f5c6bc5b366a1c9
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Private Sub DragStart()
Dragging = True
offsetPos.X = MousePosition.X - Left
offsetPos.Y = MousePosition.Y - Top
End Sub
Private Sub Drag(e As MouseEventArgs)
If e.Button = MouseButtons.Left Then
If Dragging = True Then
Me.Location = GetPos(offsetPos)
End If
End If
End Sub
Private Sub DragEnd()
If Dragging = True Then
Me.Location = GetPos(offsetPos)
End If
Dragging = False
End Sub
Private Function GetPos(aPos) As Point
GetPos.Y = MousePosition.Y - aPos.Y
GetPos.X = MousePosition.X - aPos.X
'スクリーンフレームへの吸着
If GetPos.Y < marginsize Then GetPos.Y = 0
If GetPos.X < marginsize Then GetPos.X = 0
If (GetPos.Y + Height + marginsize) > h Then GetPos.Y = h - Height
If (GetPos.X + Width + marginsize) > w Then GetPos.X = w - Width
End Function
private void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (e.ButtonState != MouseButtonState.Pressed) return;
DragMove(); //ここからDragMove
}
private void Window_MouseUp(object sender, MouseButtonEventArgs e)
{
//Draggingの終了
if (G.isDragging == true) G.isDragging = false;
}
private void Window_LocationChanged(object sender, EventArgs e)
{
if(G.isTransing == false) //画面TransitionによるLocationChangedは無視する
{
//ドラッグ中の場合はG.isDragging = trueにしておくことで最初のクリックイベントを回避
if (Mouse.LeftButton == MouseButtonState.Pressed) G.isDragging = true;
else G.isDragging = false;
//スクリーン縁への吸着
var NewPos = GetPos();
var hwnd = new WindowInteropHelper(this).Handle;
NativeMethods.SetWindowPos(hwnd, IntPtr.Zero, (int)Math.Round(NewPos.X), (int)Math.Round(NewPos.Y),
(int)Math.Round(Width * G.SR), (int)Math.Round(Height * G.SR), Consts.SWP_NOZORDER);
}
}
private Point GetPos()
{
var NewWindowPos = new Point();
NewWindowPos.X = this.Left * G.SR;
NewWindowPos.Y = this.Top * G.SR;
if (NewWindowPos.X < G.marginsize) NewWindowPos.X = 0; //左辺への吸着
if (NewWindowPos.Y < G.marginsize) NewWindowPos.Y = 0; //上辺への吸着
if (NewWindowPos.X + (Width * G.SR) + G.marginsize > G.SW) NewWindowPos.X = G.SW - (Width * G.SR); //右辺への吸着
if (NewWindowPos.Y + (Height * G.SR) + G.marginsize > G.SH) NewWindowPos.Y = G.SH - (Height * G.SR); //底辺への吸着
return NewWindowPos;
}
Reference
이 문제에 관하여(이제 WPF로 바꿔보세요 (15)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/Insetrect/items/04cd8f5c6bc5b366a1c9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)