You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WPF开发音量旋钮控件参照教程代码运行报错问题求助

WPF音量旋钮控件运行问题排查

我参照公开教程开发WPF音量旋钮控件,大部分功能逻辑正常,但部分代码莫名无法运行,代码和教程内容完全一致,不清楚问题出在哪里。


相关代码

用户控件XAML代码

<UserControl x:Class="carProg.dial"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:carProgForKids"
             mc:Ignorable="d" Height="450" Width="450">
    <Grid Manipulation.ManipulationMode="All" ManipulationDelta="Grid_ManipulationDelta">
        <Ellipse Stroke="Black" Margin="30" Fill="#FFFFE15D"/>
        <Grid>
            <Grid.RenderTransform>
                <RotateTransform CenterX="225" CenterY="225" Angle="{Binding Angle}" />
            </Grid.RenderTransform>
            <Ellipse Fill="#FFFFFDF3" 
                     Height="100" Stroke="Black" Margin="0"
                     VerticalAlignment="Top" Width="100"/>
        </Grid>
    </Grid>
</UserControl>

后台C#代码

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace carProg
{
    public partial class dial : UserControl, INotifyPropertyChanged
    {
        public dial()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        private void Grid_ManipulationDelta(object sender, ManipulationDeltaEventArgs e)
        {
            this.Angle = GetAngle(e.Position, this.RenderSize);
            this.Amount = (int)(this.Angle / 360 * 100);
        }

        int m_Amount = default(int);
        public int Amount { 
            get { return m_Amount; } 
            set { SetProperty(ref m_Amount, value); 
        } }

        double m_Angle = default(double);
        public double Angle { 
            get { return m_Angle; } 
            set { SetProperty(ref m_Angle, value); 
        } }

        public event PropertyChangedEventHandler PropertyChanged;
        void SetProperty<T>(ref T storage, T value, [System.Runtime.CompilerServices.CallerMemberName]);

        public enum Quadrants : int { nw = 2, ne = 1, sw = 4, se = 3 }
        private double GetAngle(Point touchPoint, Size circleSize)
        {
            var _X = touchPoint.X - (circleSize.Width / 2d);
            var _Y = circleSize.Height - touchPoint.Y - (circleSize.Height / 2d);
            var _Hypot = Math.Sqrt(_X * _X + _Y * _Y);
            var _Value = Math.Asin(_Y / _Hypot) * 180 / Math.PI;
            var _Quadrant = (_X >= 0) ?
                (_Y >= 0) ? Quadrants.ne : Quadrants.se :
                (_Y >= 0) ? Quadrants.nw : Quadrants.sw;
            switch (_Quadrant)
            {
                case Quadrants.ne: _Value = 090 - _Value; break;
                case Quadrants.nw: _Value = 270 + _Value; break;
                case Quadrants.se: _Value = 090 - _Value; break;
                case Quadrants.sw: _Value = 270 + _Value; break;
            }
            return _Value;
        }
    }
}

报错信息

  • e.Position报错

错误CS1061 'ManipulationDeltaEventArgs'未包含'Position'的定义,且找不到可接受类型为'ManipulationDeltaEventArgs'的第一个参数的可访问扩展方法'Position'(是否缺少using指令或程序集引用?)

  • SetProperty报错

错误CS7036 未提供与'dial.SetProperty(ref T, T, ?)'的必需形参对应的实参

  • CallerMemberName相关报错

错误CS1061 'ManipulationDeltaEventArgs'未包含'Position'的定义,且找不到可接受类型为'ManipulationDeltaEventArgs'的第一个参数的可访问扩展方法'Position'(是否缺少using指令或程序集引用?)

  • XAML Grid标签报错

错误:指定元素上未激活操作功能


补充更新

更新1:错误截图

错误截图

更新2:预期实现效果

旋钮效果图

更新3:鼠标模拟触摸实现方案

如果需要让鼠标实现和触摸设备一致的操作效果,可按以下步骤操作:

  1. 项目中引入MouseTouchDevice.cs类,代码如下:
public class MouseTouchDevice : TouchDevice, ITouchDevice
{
//Class Members

private static MouseTouchDevice device;

public Point Position { get; set; }

//Public Static Methods

public static void RegisterEvents(FrameworkElement root)
{
    root.PreviewMouseDown += MouseDown;
    root.PreviewMouseMove += MouseMove;
    root.PreviewMouseUp += MouseUp;
    root.LostMouseCapture += LostMouseCapture;
    root.MouseLeave += MouseLeave;
}

//Private Static Methods

private static void MouseDown(object sender, MouseButtonEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.ReportUp();
        device.Deactivate();
        device = null;
    }
    device = new MouseTouchDevice(e.MouseDevice.GetHashCode());
    device.SetActiveSource(e.MouseDevice.ActiveSource);
    device.Position = e.GetPosition(null);
    device.Activate();
    device.ReportDown();
}

private static void MouseMove(object sender, MouseEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.Position = e.GetPosition(null);
        device.ReportMove();
    }
}

private static void MouseUp(object sender, MouseButtonEventArgs e)
{
    LostMouseCapture(sender, e);
}

static void LostMouseCapture(object sender, MouseEventArgs e)
{
    if (device != null &&
        device.IsActive)
    {
        device.Position = e.GetPosition(null);
        device.ReportUp();
        device.Deactivate();
        device = null;
    }
}

static void MouseLeave(object sender, MouseEventArgs e)
{
    LostMouseCapture(sender, e);
}

//Constructors

public MouseTouchDevice(int deviceId) :
    base(deviceId)
{
    Position = new Point();
}

//Overridden methods

public override TouchPointCollection GetIntermediateTouchPoints(IInputElement relativeTo)
{
    return new TouchPointCollection();
}

public override TouchPoint GetTouchPoint(IInputElement relativeTo)
{
    Point point = Position;
}
}
  1. 在对应页面构造函数中添加注册代码:
public watchingMovie(String movie)
{
    InitializeComponent();
    MouseTouchDevice.RegisterEvents(this);
    ...
}

内容的提问来源于stack exchange,提问作者StealthRT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 12:36:04