如何在CustomControl的一部分上获取鼠标位置

讲师

在制作customcontrol时,我试图获得鼠标在Canvas上的位置,该Canvas是我的自定义控件内的容器。问题是,当我将customcontrol放在测试应用程序中时,仅是窗口中的网格,我得到的总是鼠标在窗口本身上的位置,而不是鼠标在customcontrol上的位置。

public class HueWheel : Control
{
    static HueWheel()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(HueWheel), new FrameworkPropertyMetadata(typeof(HueWheel)));
    }
    private bool _isPressed = false;
    //private Canvas _templateCanvas = null;
    private Canvas _PART_FirstCanvas;
    private Canvas _PART_SecondCanvas;
    private Slider _PART_Slider;

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _PART_FirstCanvas = (Canvas)GetTemplateChild("PART_FirstCanvas");
        _PART_SecondCanvas = (Canvas)GetTemplateChild("PART_SecondCanvas");
        _PART_Slider = (Slider)GetTemplateChild("PART_Slider");
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        if (_isPressed)
        {
            const double RADIUS = 150;
            Point newPos = e.GetPosition(_PART_SecondCanvas);
            double angle = MyHelper.GetAngleR(newPos, RADIUS);
            _PART_Slider.Value = (_PART_Slider.Maximum - _PART_Slider.Minimum) * angle  / (2 * Math.PI);
        }
    }

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        _isPressed = true;
    }

    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        _isPressed = false;
    }
}

这是Generic.xaml中包含的xaml

<Style TargetType="{x:Type local:HueWheel}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:HueWheel}">
                <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                    <Slider x:Name="PART_Slider">
                        <Slider.Template>
                            <ControlTemplate>
                                <Canvas x:Name="PART_FirstCanvas" Width="300" Height="300">
                                        <Image Stretch="Fill" Source="Assets/HueCircle.PNG" Focusable="False" Height="300" Width="300" RenderTransformOrigin="0.5,0.5">
                                            <Image.RenderTransform>
                                                <TransformGroup>
                                                    <ScaleTransform/>
                                                    <SkewTransform/>
                                                    <RotateTransform Angle="270"/>
                                                    <TranslateTransform/>
                                                </TransformGroup>
                                            </Image.RenderTransform>
                                        </Image>
                                        <Ellipse Fill="Transparent" Width="300" Height="300" Canvas.Left="0" Canvas.Top="0"/>
                                        <Canvas x:Name="PART_SecondCanvas">
                                            <Line Stroke="Transparent" StrokeThickness="5" X1="150" Y1="150" X2="150" Y2="0"/>
                                            <Ellipse Fill="Black" Width="20" Height="20" Canvas.Left="140" Canvas.Top="30"/>
                                            <Canvas.RenderTransform>
                                                <RotateTransform CenterX="150" CenterY="150">
                                                    <RotateTransform.Angle>
                                                        <MultiBinding Converter="{StaticResource ValueAngleConverter}">
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Value"/>
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Minimum"/>
                                                            <Binding RelativeSource="{RelativeSource TemplatedParent}" Path="Maximum"/>
                                                        </MultiBinding>
                                                    </RotateTransform.Angle>
                                                </RotateTransform>
                                            </Canvas.RenderTransform>
                                        </Canvas>
                                    </Canvas>
                            </ControlTemplate>
                        </Slider.Template>
                    </Slider>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

另外,仅当鼠标在画布上时才输出鼠标位置,因此在这里工作的一半左右……有点混乱。

这是我用于角度计算的两个函数:

public static double GetAngle(double value, double maximum, double minimum)
{
    double current = (value / (maximum - minimum)) * 360;
    if (current == 360)
        current = 359.999;

    return current;
}


public static double GetAngleR(Point pos, double radius)
{
    Point center = new Point(radius, radius);
    double xDiff = center.X - pos.X;
    double yDiff = center.Y - pos.Y;
    double r = Math.Sqrt(xDiff * xDiff + yDiff * yDiff);

    double angle = Math.Acos((center.Y - pos.Y) / r);

    if (pos.X < radius)
        angle = 2 * Math.PI - angle;

    if (Double.IsNaN(angle))
        return 0.0;
    else
        return angle;
}

有什么提示吗?

谢谢

狮身人面像

_PART_SecondCanvas并且_PART_FirstCanvas为null,因为它们属于子Slider的控件模板,而不是“主” HueWheel模板。因此,您无法GetTemplateChild()通过HueWheel与他们联系。

OnApplyTemplate(),你需要先找到滑块,然后应用它的模板,最后调用FindName()模板找到画布元素:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    //_PART_FirstCanvas = (Canvas)GetTemplateChild("PART_FirstCanvas");
    //_PART_SecondCanvas = (Canvas)GetTemplateChild("PART_SecondCanvas");
    _PART_Slider = (Slider)GetTemplateChild("PART_Slider");

    _PART_Slider.ApplyTemplate();

    var sliderTemplate = _PART_Slider.Template;
    _PART_FirstCanvas  = (Canvas)sliderTemplate.FindName("PART_FirstCanvas",  _PART_Slider);
    _PART_SecondCanvas = (Canvas)sliderTemplate.FindName("PART_SecondCanvas", _PART_Slider);
}

资料来源:如何获得ContentPresenter的子代?

实际找到_PART_SecondCanvas和之后_PART_FirstCanvas,您的OnMouseMove()函数应该可以完成您所期望的工作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在鼠标悬停的位置显示模糊图像的一部分?

如何根据鼠标指针从JLabel获取文本的一部分

如何获取 URL 的一部分?

如何删除获取ID的一部分

如何获取当前的一部分URL?

如何在Nginx中获取$ host变量的一部分?

如何在OCaml / ReasonML中获取列表的一部分?

如何在JavaScript中获取字符串的最后一部分?

如何在jQuery中获取文本框ID的一部分

如何在opencv中获取矩阵的一部分

如何在BigQuery Standard SQL中获取数组的一部分?

如何在返回值中获取列表的一部分

如何在单词索引后获取标题的一部分 - wordpress

如何在Ant设计中获取当前URL的最后一部分

如何在Haskell中获取数字的一部分

如何在赛普拉斯中获取url的一部分

如何在 Oracle 中获取 JSON 字符串的一部分

PHP中的Regex:如何在最后一部分URL中获取单词?

如何在C#中获取string []数组的一部分

如何在 JavaScript 中获取 var 的一部分?

如何在磁盘的一部分上安装Ubuntu?

如何在Xubuntu 18.04上截取屏幕的一部分?

如何在PostgreSQL中的列的一部分上分组?

如何在Gnuplot上以对数刻度设置x轴的一部分?

如何在CAShapeLayer上仅填充形状的一部分

如何在Azure上编写应用程序的一部分?

如何在 Pandas 数据帧的一部分上使用 std 函数?

返回我将鼠标位置与 python 中的坐标匹配的列表的一部分

python:如何通过鼠标事件删除轮廓图的一部分(matplotlib)