2012-04-13 2 views
2

저는 WPF에 새로 입문했습니다. 그래서이 대부분을 어렵지만 재미있게 배웁니다. 나는 HSV와 같은 colorpicker usercontrol을 만들고 있는데, "선택자"가 타원 영역 (실제로는 원)으로 제한되어 있기 때문에 사용하는 엄지 손가락을 사용하여 동작을 얻고 싶습니다. 바깥쪽으로 이동할 때, 선택자는 측면으로 붙잡고 전혀 움직이지 않아야합니다. 이것이 가장 일반적인 GUI 동작이라고 생각합니다. 그래서 그것이 어떻게 동작해야하는지입니다. 자유롭게 더 나은 행동을 제안하십시오!엄지 손가락을 타원형 영역으로 제한

일반적으로 알려져 있고 권장되는 해결책이 있습니까? 아니면 매번 바퀴를 다시 발명해야합니까?

이 문제를 해결하는 방법에 대한 좋은 아이디어가 있습니까?

코드 숨김

public partial class HSVColorPicker : UserControl 
{ 
    public HSVColorPicker() 
    { 
     InitializeComponent(); 
    } 

    void onDragDelta(object sender, DragDeltaEventArgs e) 
    { 
     Canvas.SetLeft(thumb, Canvas.GetLeft(thumb) + e.HorizontalChange); 
     Canvas.SetTop(thumb, Canvas.GetTop(thumb) + e.VerticalChange); 
    } 
} 

XAML : 여기에있어하지만, 엄지 손가락은 항상 커서 뒤에 끌고있다

<Grid> 
    <Canvas x:Name="canvas"> 
     <Image x:Name="wheel" Source="colorwheel.png" Width="300" Margin="5,5,0,0"/> 
     <Thumb Name="thumb" DragDelta="onDragDelta" Canvas.Left="104" Canvas.Top="68" Template="{StaticResource thumbTemplate}" /> 
    </Canvas> 
</Grid> 

이를 생성하는 또 다른 방법이있다? 앞에서 말했듯이 저는 WPF와 GUI를 처음 사용하기 때문에 제게 발생하지 않은 명백한 해결책이있을 수 있습니다.)

답변

1

좀 다시 생각을했고 대신 더미 원 (라는 이름의 엄지 손가락)를 사용하여 완전히 엄지 손가락을 떨어졌다. 이제 캔버스에서 mousedown, mousedown, mouseup 및 mousemove를 듣고 무엇이 가능해야하는지 결정합니다. 마우스가 영역 밖으로 나갈 때 엄지 손가락이 컬러휠 가장자리에 붙어 있지만 테두리는 경계에서 쉽게 구할 수 있도록 색 휠보다 약간 큽니다. 완료되지 않았지만 내 질문을 해결하므로 지금은 그대로 게시합니다.

private bool mousePressed { get; set; } 
    private bool mouseWithinArea { get; set; } 
    private Point circleMiddlePoint { get; set; } 
    private int margin; 
    private double mPX; 
    private double mPY; 
    private double localXpos; 
    private double globalXpos 
    { 
     get 
     { 
      return localXpos + mPX; 
     } 
     set 
     { 
      localXpos = value - mPX; 
      Canvas.SetLeft(thumb, value); 
     } 
    } 
    private double localYpos; 
    private double globalYpos 
    { 
     get 
     { 
      return mPY - localYpos; 
     } 
     set 
     { 
      localYpos = mPY - value; 
      Canvas.SetTop(thumb, value); 
     } 
    } 

    public HSVColorPicker() 
    { 
     InitializeComponent(); 
     wheel.Width = 300; 
     margin = 15; 
     mPX = 150+margin; 
     mPY = 150+margin; 
     circleMiddlePoint = new Point(mPX, mPY); 
    } 

    private void CalcPosition(double X, double Y) 
    { 
     double radius = wheel.Width/2.0; 
     double vectorX = X - mPX; 
     double vectorY = Y - mPY; 
     double distance = Math.Sqrt(vectorX * vectorX + vectorY * vectorY); 
     if (distance > radius) 
     { 
      double factor = radius/distance; 
      vectorX *= factor; 
      vectorY *= factor; 
     } 
     globalXpos = vectorX + mPX; 
     globalYpos = vectorY + mPY; 
    } 

    private void wheel_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     if (mouseWithinArea) 
     { 
      mousePressed = true; 
      Point mousePoint = e.GetPosition(this); 
      CalcPosition(mousePoint.X, mousePoint.Y); 
     } 
    } 

    private void wheel_MouseMove(object sender, MouseEventArgs e) 
    { 
     Point mousePoint = e.GetPosition(this); 
     double relX = mousePoint.X - mPX; 
     double relY = mPY - mousePoint.Y; 
     if (mouseWithinArea) 
     { 
      if (Math.Sqrt(relX * relX + relY * relY) > 150+margin) 
      { 
       mouseWithinArea = false; 
      } 
      else 
      { 
       if (mousePressed) 
       { 
        CalcPosition(mousePoint.X, mousePoint.Y); 
       } 
      } 
     } 
     else 
     { 
      if (Math.Sqrt(relX * relX + relY * relY) < 150+margin) 
      { 
       mouseWithinArea = true; 
       if (mousePressed) 
       { 
        CalcPosition(mousePoint.X, mousePoint.Y); 
       } 
      } 
     } 
    } 

    private void wheel_MouseUp(object sender, MouseButtonEventArgs e) 
    { 
     mousePressed = false; 
    } 
} 

<Canvas x:Name="canvas" Background="Transparent" MouseDown="wheel_MouseDown" MouseMove="wheel_MouseMove" MouseUp="wheel_MouseUp" Width="330" Height="330"> 
     <Image x:Name="wheel" Source="colorwheel.png" Width="300" Margin="15,15,0,0" /> 
     <Ellipse Margin="0,0,0,0" 
       x:Name="outerEll" 
       Stroke="Silver" 
       StrokeThickness="15" 
       Width="330" 
       Height="330"/> 
     <Ellipse Name="thumb" Stroke="Black" Fill="Silver" Canvas.Left="150" Canvas.Top="150" Width="15" Height="15" Margin="-12" /> 
    </Canvas> 
0

엄지의 중심을 색상환 내에두기를 원합니다.

엄지의 중심과 색상환의 중심 (즉, 캔버스의 중심) 사이의 거리가 또는 색상환의 반경과 같아야합니다 (즉, 색상환의 반 당신의 캔버스의 측면).

테스트되지 않은 C# 코드 :

void onDragDelta(object sender, DragDeltaEventArgs e) 
{ 
    double radius = canvas.RenderSize.Width/2.0; 
    double thumbCenterX = Canvas.GetLeft(thumb) - thumb.RenderSize.Width + e.HorizontalChange; 
    double thumbCenterY = Canvas.GetTop(thumb) - thumb.RenderSize.Height + e.VerticalChange; 
    double colorWheelCenterX = canvas.RenderSize.Width/2.0; 
    double colorWheelCenterY = canvas.RenderSize.Height/2.0; 
    double vectorX = thumbCenterX - colorWheelCenterX; 
    double vectorY = thumbCenterY - colorWheelCenterY; 
    double distance = Math.Sqrt(vectorX * vectorX + vectorY * vectorY); 
    if(distance > radius) { 
     double factor = radius/distance; 
     vectorX *= factor; 
     vectorY *= factor; 
    } 
    Canvas.SetLeft(thumb, colorWheelCenterX + vectorX - thumb.RenderSize.Width/2.0); 
    Canvas.SetTop(thumb, colorWheelCenterY + vectorY - thumb.RenderSize.Height/2.0); 
} 
+0

커서가 바깥쪽에 움직일 수는 없지만 확실히 큰 덩어리를 만들었습니다. 엄지 손가락과 커서도 커서가 나가고 다시 들어가면 분리됩니다. 따라서 일부 디버깅을하고 대답을 수락합니다. 완료되면 내 최종 솔루션을 게시합니다. – Bob

관련 문제