我想在我的WPF应用程序中创建一个控件,允许用户在框/圆内拖动点。这将用于驱动摄影机的平移值和倾斜值。
我不确定如何创建这样的控件。下面的图片是我想要开发的控件类型的示例。
发布于 2019-08-14 19:28:05
这里有一个非常快速的解决方案来帮助您开始。
对于XAML,我使用了一个用于“点”的Ellipse
控件。椭圆被放在一个Canvas
控件中(它允许点在周围移动):
<Grid Background="White"
MouseUp="ParentOnMouseUp">
<Canvas x:Name="canvas"
Background="Green"
Width="200"
Height="200"
HorizontalAlignment="Center"
VerticalAlignment="Center"
MouseMove="CanvasOnMouseMove">
<!-- Implement your blue circle b/g as an Image control here ... />
<Ellipse x:Name="dot"
Width="20"
Height="20"
Fill="Blue"
Loaded="DotOnLoaded"
MouseDown="DotOnMouseDown"/>
</Canvas>
</Grid>
首先,我处理椭圆的MouseDown
事件:
private void DotOnMouseDown(object sender, MouseButtonEventArgs e)
{
_isDraggingDot = true;
}
我在这里所做的就是设置一个标志来指示我开始拖动点。
接下来,我处理Canvas MouseMove
事件,这是我移动圆点的地方。它包括确保点不会偏离画布的逻辑:
private void CanvasOnMouseMove(object sender, MouseEventArgs e)
{
if (_isDraggingDot)
{
var mousePos = e.GetPosition(canvas);
var x = mousePos.X;
if (x < 0)
{
x = 0;
}
if (x > canvas.Width)
{
x = canvas.Width;
}
var y = mousePos.Y;
if (y < 0)
{
y = 0;
}
if (y > canvas.Height)
{
y = canvas.Height;
}
dot.SetValue(Canvas.LeftProperty, x - (dot.Width / 2.0)); // offset ensures dot is centred on mouse pointer
dot.SetValue(Canvas.TopProperty, y - (dot.Height / 2.0));
}
}
这也是您计算点相对于中心的垂直和水平偏移的位置,并使用这些值来更新平移和倾斜。
最后,我在外部控件(我的示例中是网格)上实现了MouseUp
事件:
private void ParentOnMouseUp(object sender, MouseButtonEventArgs e)
{
_isDraggingDot = false;
CentreDot();
}
private void CentreDot()
{
dot.SetValue(Canvas.LeftProperty, (canvas.Width / 2.0) - (dot.Width / 2.0));
dot.SetValue(Canvas.TopProperty, (canvas.Height / 2.0) - (dot.Height / 2.0));
}
处理外部控件上的事件的原因是确保如果用户在画布外部释放鼠标按钮,点将返回中心。(请注意,我还在Grid上设置了b/g颜色,否则它默认为透明,不会检测鼠标事件!)
最后,我连接了椭圆的Loaded
事件,以便在UI加载时将点放在中心位置:
private void DotOnLoaded(object sender, RoutedEventArgs e)
{
CentreDot();
}
正如我所提到的,这只是一个快速的解决方案,其中点只需跟随鼠标。如果你不喜欢这样,你可以计算鼠标(垂直和水平方向)离画布中心的距离,然后使用这些值中的一小部分将点定位在远离中心的位置,这实际上需要更多的鼠标移动来移动点,这可能感觉更“自然”。
另一个想法可能是将点的位置“捕捉”到四个箭头按钮中最近的一个(N,S,E,W),甚至包括中间的点(NE,SE,SW,NW)。
https://stackoverflow.com/questions/57478629
复制相似问题