Copyright © 2022-2024 aizws.net · 网站版本: v1.2.6·内部版本: v1.23.3·
页面加载耗时 0.00 毫秒·物理内存 69.8MB ·虚拟内存 1300.5MB
欢迎来到 AI 中文社区(简称 AI 中文社),这里是学习交流 AI 人工智能技术的中文社区。 为了更好的体验,本站推荐使用 Chrome 浏览器。
WPF 实现拟物音量控件
控件名:Wheel
作者:WPFDevelopersOrg -俞宏伟
原文链接:https://github.com/WPFDevelopersOrg/SimulationControl
实现代码
1)创建Wheel.xaml代码如下:
<UserControl x:Class="TopControl.Wheel" 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:TopControl" mc:Ignorable="d" Width="30" Height="180"> <Grid> <!-- 进度 --> <Grid Width="2" Background="#0a0a0a" Height="180" HorizontalAlignment="Left" VerticalAlignment="Bottom"/> <Grid Width="2" x:Name="Grid_Value" Height="0" HorizontalAlignment="Left" VerticalAlignment="Bottom"> <Grid Height="180" VerticalAlignment="Bottom"> <Grid.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="#f0d967"/> <GradientStop Offset="1" Color="#33b08d"/> </LinearGradientBrush> </Grid.Background> </Grid> </Grid> <Grid Background="#0a0a0a" Width="26" HorizontalAlignment="Right" Height="180" Margin="2,0,0,0"/> <!-- 滚轮 --> <Grid x:Name="WheelArea" Height="176" Width="22" HorizontalAlignment="Right" Margin="0,0,2,0" MouseDown="WheelArea_MouseDown" MouseMove="WheelArea_MouseMove" MouseUp="WheelArea_MouseUp" MouseWheel="WheelArea_MouseWheel"> <Grid.Background> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="#141414" Offset="0"/> <GradientStop Color="#3c3c3c" Offset="0.5"/> <GradientStop Color="#141414" Offset="1"/> </LinearGradientBrush> </Grid.Background> <Grid x:Name="LayerBox" IsHitTestVisible="False"/> </Grid> </Grid> </UserControl>
2)创建Wheel.xaml.cs代码如下:
using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace TopControl { public partial class Wheel : UserControl { public Wheel() { InitializeComponent(); Loaded += Wheel_Loaded; } #region 属性 public int MinValue { get; set; } = -720; public int MaxValue { get; set; } = 720; public int Value { get; set; } = -720; #endregion #region 控件事件 private void Wheel_Loaded(object sender, RoutedEventArgs e) { InitLayer(); } private void WheelArea_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left) { BeginDrag(); } } private void WheelArea_MouseMove(object sender, MouseEventArgs e) { if (_dragMode) { Drag(); } } private void WheelArea_MouseUp(object sender, MouseButtonEventArgs e) { if (e.ChangedButton == MouseButton.Left && _dragMode) { EndDrag(); } } private void WheelArea_MouseWheel(object sender, MouseWheelEventArgs e) { if (_dragMode) return; int offset = e.Delta / 120; if (offset < 0 && Value > MinValue) { Value += offset; UpdateProgress(); _wheelLayer.AngleOffset -= offset * _wheelSpeed; _wheelLayer.UpdateLayer(); } else if (offset > 0 && Value < MaxValue) { Value += offset; UpdateProgress(); _wheelLayer.AngleOffset -= offset * _wheelSpeed; _wheelLayer.UpdateLayer(); } } #endregion #region 鼠标操作 private void BeginDrag() { _dragMode = true; WheelArea.CaptureMouse(); _dragStart = Mouse.GetPosition(WheelArea); _angleStart = _wheelLayer.AngleOffset; _valueStart = Value; _offsetDown = Value - MinValue; _offsetUp = Value - MaxValue; } private void Drag() { double offset_y = Mouse.GetPosition(WheelArea).Y - _dragStart.Y; if (offset_y < _offsetUp) offset_y = _offsetUp; else if (offset_y > _offsetDown) offset_y = _offsetDown; double offset_angle = offset_y * _wheelSpeed; Value = _valueStart - (int)offset_y; _wheelLayer.AngleOffset = _angleStart + offset_angle; UpdateProgress(); _wheelLayer.UpdateLayer(); } private void EndDrag() { _dragMode = false; WheelArea.ReleaseMouseCapture(); } #endregion #region 私有方法 /// <summary> /// 初始化图层 /// </summary> private void InitLayer() { _wheelLayer.Width = LayerBox.ActualWidth; _wheelLayer.Height = LayerBox.ActualHeight; LayerBox.Children.Add(_wheelLayer); _wheelLayer.Init(); _wheelLayer.UpdateLayer(); } /// <summary> /// 更新进度 /// </summary> private void UpdateProgress() { Grid_Value.Height = (double)(Value - MinValue) / (MaxValue - MinValue) * 180; } #endregion #region 字段 private readonly WheelLayer _wheelLayer = new WheelLayer(); private Point _dragStart = new Point(); private double _angleStart = 0; private int _valueStart = 0; private bool _dragMode = false; /// <summary>滚轮速度</summary> private readonly double _wheelSpeed = 0.7; /// <summary>最大向上偏移</summary> private double _offsetUp; /// <summary>最大向下偏移</summary> private double _offsetDown; #endregion } }
3)创建WheelLayer.cs代码如下:
using MathUtil; using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Media; using WpfUtil; namespace TopControl { public class WheelLayer : SingleLayer { #region 属性 /// <summary>槽高度:180px - 上下边框(4px)</summary> public int GrooveHeight { get; set; } = 176; /// <summary>角度:圆弧切线与槽边的夹角</summary> public int Angle { get; set; } = 90; /// <summary>刻度线数量</summary> public int LineCount { get; set; } = 90; /// <summary>角度偏移</summary> public double AngleOffset { get; set; } = 0; #endregion #region 公开方法 public override void Init() { // 起点、终点、中点 Point2D startPoint = new Point2D(0, 0); Point2D endPoint = new Point2D(GrooveHeight, 0); Point2D centerPoint = startPoint.CenterWith(endPoint); // 向量:中点 -> 起点 Vector2 centerToStart = new Vector2(centerPoint, startPoint); centerToStart.Rotate(-90); // 向量:终点 -> 中点 Vector2 endToCenter = new Vector2(endPoint, centerPoint); endToCenter.Rotate(-90 + Angle); // 圆心 _circleCenter = centerToStart.IntersectionWith(endToCenter); // 向量:圆心 -> 起点 Vector2 vector = new Vector2(_circleCenter, startPoint); _radius = vector.Distance; _anglePerLine = 360.0 / LineCount; } protected override void OnUpdate() { // 最高点 Point2D top = new Point2D(_circleCenter.X, _circleCenter.Y - _radius); // 向量:圆心 -> 最高点 Vector2 vector = new Vector2(_circleCenter, top); double max = Math.Abs(vector.Target.Y); // 偏移角度 vector.Rotate(AngleOffset); // 开始旋转计算刻度位置 List<Point2D> pointList = new List<Point2D>(); for (int counter = 0; counter < LineCount; counter++) { if (vector.Target.Y < 0) pointList.Add(vector.Target); vector.Rotate(-_anglePerLine); } // 绘制刻度线 foreach (var item in pointList) DrawHorizontalLine(item.X, Math.Abs(item.Y) / max); } #endregion #region 私有方法 /// <summary> /// 绘制水平线 /// </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] private void DrawHorizontalLine(double y, double opacity) { Pen pen = new Pen(new SolidColorBrush(Color.FromArgb((byte)(opacity * 255), 32, 32, 32)), 1); Pen pen2 = new Pen(new SolidColorBrush(Color.FromArgb((byte)(opacity * 255), 64, 64, 64)), 1); _dc.DrawLine(pen, new Point(2, y - 0.5), new Point(Width - 2, y - 0.5)); _dc.DrawLine(pen2, new Point(2, y + 0.5), new Point(Width - 2, y + 0.5)); } #endregion #region 字段 /// <summary>圆心</summary> private Point2D _circleCenter = new Point2D(0, 0); /// <summary>半径</summary> private double _radius = 0; /// <summary>刻度线之间的夹角</summary> private double _anglePerLine = 0; #endregion } }
4)创建WheelExample.xaml代码如下:
<wd:Window x:Class="TopControl.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:TopControl" xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" mc:Ignorable="d" Background="#1e1e1e" Title="https://github.com/WPFDevelopersOrg/SimulationControl - 俞宏伟" Height="450" Width="800"> <Grid> <local:Wheel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50"/> </Grid> </wd:Window>
效果图
以上就是基于WPF实现拟物音量控件的详细内容,更多关于WPF拟物音量控件的资料请关注编程教程其它相关文章!
最近在做微信开发时用到了一些json的问题,就是把微信返回回来的一些json数据做一些处理,但是之前json掌握的不好,浪费了好多时间在查找一些json有关的转换问题,我所知道的方法只有把json序 ...