중간 마우스 버튼 (일명 : 마우스 휠)을 클릭 한 다음 마우스를 약간 아래로 이동하면 IE 및 대부분의 Windows 응용 프로그램에서 스크롤 할 수 있습니다. 이 동작은 기본적으로 WPF 컨트롤에없는 것 같습니다? 해결 방법, 해결 방법 또는 누락 된 것이 있습니까?WPF ScrollViewer 중간 클릭 스크롤을 어떻게 만듭니 까?
답변
3 마우스 이벤트 (MouseDown
, MouseUp
, MouseMove
)를 사용하여이를 수행하는 방법을 발견했습니다.
<Grid>
<ScrollViewer MouseDown="ScrollViewer_MouseDown" MouseUp="ScrollViewer_MouseUp" MouseMove="ScrollViewer_MouseMove">
<StackPanel x:Name="dynamicLongStackPanel">
</StackPanel>
</ScrollViewer>
<Canvas x:Name="topLayer" IsHitTestVisible="False" />
</Grid>
대신 코드 숨김에서 이벤트의 동작을 작성하는 더 나은 것,하지만 모두가 필요한 라이브러리를 가지고 있으며, 또한 그렇게하지 : 그들의 핸들러는 아래의 XAML에 ScrollViewer
요소에 부착 Canvas
과 연결하는 방법을 알고 있어야합니다.
이벤트 핸들러 :
private bool isMoving = false; //False - ignore mouse movements and don't scroll
private bool isDeferredMovingStarted = false; //True - Mouse down -> Mouse up without moving -> Move; False - Mouse down -> Move
private Point? startPosition = null;
private double slowdown = 200; //The number 200 is found from experiments, it should be corrected
private void ScrollViewer_MouseDown(object sender, MouseButtonEventArgs e)
{
if (this.isMoving == true) //Moving with a released wheel and pressing a button
this.CancelScrolling();
else if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed)
{
if (this.isMoving == false) //Pressing a wheel the first time
{
this.isMoving = true;
this.startPosition = e.GetPosition(sender as IInputElement);
this.isDeferredMovingStarted = true; //the default value is true until the opposite value is set
this.AddScrollSign(e.GetPosition(this.topLayer).X, e.GetPosition(this.topLayer).Y);
}
}
}
private void ScrollViewer_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Released && this.isDeferredMovingStarted != true)
this.CancelScrolling();
}
private void CancelScrolling()
{
this.isMoving = false;
this.startPosition = null;
this.isDeferredMovingStarted = false;
this.RemoveScrollSign();
}
private void ScrollViewer_MouseMove(object sender, MouseEventArgs e)
{
var sv = sender as ScrollViewer;
if (this.isMoving && sv != null)
{
this.isDeferredMovingStarted = false; //standard scrolling (Mouse down -> Move)
var currentPosition = e.GetPosition(sv);
var offset = currentPosition - startPosition.Value;
offset.Y /= slowdown;
offset.X /= slowdown;
//if(Math.Abs(offset.Y) > 25.0/slowdown) //Some kind of a dead space, uncomment if it is neccessary
sv.ScrollToVerticalOffset(sv.VerticalOffset + offset.Y);
sv.ScrollToHorizontalOffset(sv.HorizontalOffset + offset.X);
}
}
방법은 AddScrollSign
이 예제가 작동 RemoveScrollSign
를 호출 제거 할 경우
private void AddScrollSign(double x, double y)
{
int size = 50;
var img = new BitmapImage(new Uri(@"d:\middle_button_scroll.png"));
var adorner = new Image() { Source = img, Width = size, Height = size };
//var adorner = new Ellipse { Stroke = Brushes.Red, StrokeThickness = 2.0, Width = 20, Height = 20 };
this.topLayer.Children.Add(adorner);
Canvas.SetLeft(adorner, x - size/2);
Canvas.SetTop(adorner, y - size/2);
}
private void RemoveScrollSign()
{
this.topLayer.Children.Clear();
}
예 :
그리고 마지막으로 한 말 :하지만 스크롤 아이콘을 설정 2 가지 방법으로 확장 한 방법 Press -> Immediately Release -> Move
몇 가지 문제가있다. 사용자가 마우스 왼쪽 버튼이나 키보드 키를 클릭하거나 응용 프로그램이 포커스를 잃는 경우 스크롤을 취소해야합니다. 많은 사건들이 있으며 나는 그들을 다룰 시간이 없다.
표준 방법 Press -> Move -> Release
은 문제없이 작동합니다.
+1 솔루션에 대한 의견이 있으 십니다. 제 답변을 참조하십시오. –
vorrtex 멋진 솔루션 게시 위로 올리기하십시오주세요!
나는 그 해결책에 대한 몇 가지 제안을하고 있지만, 의견에 모두 들어 맞기에는 너무 길어서 별도의 답변을 게시하고 직접 알려줍니다!
보도 자료 -> 릴리스 -> 이동 문제를 언급합니다. 마우스가 더 이상 ScrollViewer를 넘지 않아도 MouseCapturing을 사용하여 MouseEvents를 가져와야합니다. 나는 그것을 테스트하지 않았지만, 당신의 솔루션도 Press->Move->Move outside of ScrollViewer->Release
에서 실패했다고 생각합니다. Mousecapturing도 그것을 처리 할 것입니다.
또한 행동을 사용하여 언급합니다. 차라리 추가 종속성이 필요없는 attached behavior을 제안합니다.
분명히 여분의 캔버스를 사용하지 말고 Adorner에서해야합니다.
ScrollViewer 자체는 AdornerLayer를 정의하는 ScrollContentPresenter를 호스팅합니다. 거기에 Adorner를 삽입해야합니다. 이렇게하면 더 이상의 종속성이 필요 없으며 첨부 된 동작을 IsMiddleScrollable="true"
과 같이 간단하게 유지할 수 있습니다.
MouseCapture는 구현하기 어렵지 않습니다. 몇 시간 후에이 작업을 수행 할 것입니다.그러나 다른 의견은 그렇게 평범하지 않습니다. 첨부 된 속성이나 동작을 사용하면 스크롤 이미지를'Canvas'에 추가 할 수 없습니다. 반면에'ScrollContentPresenter '컨트롤은'ScrollViewer'의 템플릿 안에 위치합니다. 내부 부품에 액세스하려면 상속 된 컨트롤을 만들어야한다고 생각합니다. 이것으로 무언가를하려고 노력할 것이지만 새로운 컨트롤이 이벤트 핸들러 세트보다 나은지 확실하지 않습니다. – vorrtex
마우스 캡처 후 MouseMove 이벤트는 한 번만 호출됩니다. 나는 움직이는 기능을 가진 메소드를 트리거 할 타이머를 생성해야한다. 모든 것이 점점 더 복잡해집니다. – vorrtex
@vorrtex 내일 저녁에 시간이 있습니다. 나도 멋진 소형 솔루션에 관심이있어, 나는 그것에 잠수를 취할 것입니다! –
- 1. 하단에서 웹 페이지 스크롤을 어떻게 만듭니 까?
- 2. Silverlight 버튼에서 클릭 상태를 어떻게 만듭니 까?
- 3. 런타임시 WPF 대화 상자를 어떻게 만듭니 까?
- 4. 자바 스크립트로 중간 클릭 스크롤을 사용 중지합니다.
- 5. 오버플로 : 자동 상자에서 배경 이미지 스크롤을 어떻게 만듭니 까?
- 6. WPF ScrollViewer
- 7. WPF 응용 프로그램의 Scrollviewer + Stackpanel
- 8. Perl 클래스는 어떻게 만듭니 까?
- 9. Catalyst에서 세션을 어떻게 만듭니 까?
- 10. 게임 바닥을 어떻게 만듭니 까?
- 11. 사전 항목은 어떻게 만듭니 까?
- 12. 이벤트 구독자는 어떻게 만듭니 까?
- 13. 컨테이너 파일은 어떻게 만듭니 까?
- 14. EDM에서 데이터베이스를 어떻게 만듭니 까?
- 15. 페이지 템플리트는 어떻게 만듭니 까?
- 16. 싱글턴 IEnumerable은 어떻게 만듭니 까?
- 17. 바이너리 패치는 어떻게 만듭니 까?
- 18. 모바일 사이트는 어떻게 만듭니 까?
- 19. 포인터의 배열은 어떻게 만듭니 까?
- 20. JSON Array는 어떻게 만듭니 까?
- 21. 빈 op_array는 어떻게 만듭니 까?
- 22. gitosis에서 머리를 어떻게 만듭니 까?
- 23. RSS 피드는 어떻게 만듭니 까?
- 24. 동적 URL은 어떻게 만듭니 까?
- 25. 소셜 그래프는 어떻게 만듭니 까?
- 26. CruiseControl.Net에서 속성을 어떻게 만듭니 까?
- 27. 제한된 AppDomain은 어떻게 만듭니 까?
- 28. UISplitView를 수동으로 어떻게 만듭니 까?
- 29. 런타임에 객체를 어떻게 만듭니 까?
- 30. 맞춤식 날짜는 어떻게 만듭니 까?
마우스 가운데 버튼 이벤트를 처리하는 것이 가능합니다 : http://stackoverflow.com/questions/517556/how-to-handle-the-mouse-wheel-click-event-in-wpf. 나는이 사건을 올바르게 처리하고 처리하기 위해 노력할 것이다. – vorrtex