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

时间:2016-08-05 07:30:08

标签: c# wpf

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

<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>

这是Generic.xaml中包含的xaml

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;
}

此外,仅当鼠标位于画布上时才会输出鼠标位置,因此它在这里工作了一半......很少有人混淆。

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

ERB.new(File.read(path)).src

任何提示?

谢谢

2 个答案:

答案 0 :(得分:1)

在您的代码中

Point ControlPos = e.GetPosition (this);
Point WindowPos = e.GetPosition( Application.Current.MainWindow );

会给你 - 控制和窗口坐标中的坐标。

答案 1 :(得分:1)

_PART_SecondCanvas_PART_FirstCanvas为空,因为它们属于子滑块的控件模板,而不属于“主” HueWheel 模板。因此,您无法通过HueWheel的GetTemplateChild()与他们联系。

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);
}

来源:How do I get the Children of a ContentPresenter?

实际找到_PART_SecondCanvas_PART_FirstCanvas后,您的OnMouseMove()功能应该达到预期效果。