基于WPF實(shí)現(xiàn)擬物音量控件
WPF 實(shí)現(xiàn)擬物音量控件
控件名:Wheel
作者:WPFDevelopersOrg - 俞宏偉
原文鏈接:https://github.com/WPFDevelopersOrg/SimulationControl
- 框架使用
.NET6
; Visual Studio 2022
;- 繪制使用了
Canvas
作為容器控件,DrawingContext
上繪制水平線。 - 當(dāng)鼠標(biāo)滾動(dòng)滾輪時(shí)或按下鼠標(biāo)向上向下拖動(dòng)時(shí)計(jì)算角度偏移并更新圖層。
實(shí)現(xiàn)代碼
1)創(chuàng)建 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> ????????<!--?進(jìn)度?--> ????????<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)創(chuàng)建 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?鼠標(biāo)操作 ????????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> ????????///?更新進(jìn)度 ????????///?</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)創(chuàng)建 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>刻度線數(shù)量</summary> ????????public?int?LineCount?{?get;?set;?}?=?90; ????????///?<summary>角度偏移</summary> ????????public?double?AngleOffset?{?get;?set;?}?=?0; ????????#endregion ????????#region?公開方法 ????????public?override?void?Init() ????????{ ????????????//?起點(diǎn)、終點(diǎn)、中點(diǎn) ????????????Point2D?startPoint?=?new?Point2D(0,?0); ????????????Point2D?endPoint?=?new?Point2D(GrooveHeight,?0); ????????????Point2D?centerPoint?=?startPoint.CenterWith(endPoint); ????????????//?向量:中點(diǎn)?->?起點(diǎn) ????????????Vector2?centerToStart?=?new?Vector2(centerPoint,?startPoint); ????????????centerToStart.Rotate(-90); ????????????//?向量:終點(diǎn)?->?中點(diǎn) ????????????Vector2?endToCenter?=?new?Vector2(endPoint,?centerPoint); ????????????endToCenter.Rotate(-90?+?Angle); ????????????//?圓心 ????????????_circleCenter?=?centerToStart.IntersectionWith(endToCenter); ????????????//?向量:圓心?->?起點(diǎn) ????????????Vector2?vector?=?new?Vector2(_circleCenter,?startPoint); ????????????_radius?=?vector.Distance; ????????????_anglePerLine?=?360.0?/?LineCount; ????????} ????????protected?override?void?OnUpdate() ????????{ ????????????//?最高點(diǎn) ????????????Point2D?top?=?new?Point2D(_circleCenter.X,?_circleCenter.Y?-?_radius); ????????????//?向量:圓心?->?最高點(diǎn) ????????????Vector2?vector?=?new?Vector2(_circleCenter,?top); ????????????double?max?=?Math.Abs(vector.Target.Y); ????????????//?偏移角度 ????????????vector.Rotate(AngleOffset); ????????????//?開始旋轉(zhuǎn)計(jì)算刻度位置 ????????????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)創(chuàng)建 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實(shí)現(xiàn)擬物音量控件的詳細(xì)內(nèi)容,更多關(guān)于WPF擬物音量控件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Unity Blend Tree動(dòng)畫混合樹使用入門教程
這篇文章主要為大家詳細(xì)介紹了Unity Blend Tree動(dòng)畫混合樹使用入門教程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn)
在做winform開發(fā)時(shí),如果在子線程中去設(shè)置主線程中UI控件的屬性,會(huì)出現(xiàn)“跨線程調(diào)用異?!?本文就來介紹一下C#?winform?窗體控件跨線程訪問的實(shí)現(xiàn),感興趣的可以了解一下2023-12-12Unity3D實(shí)現(xiàn)鼠標(biāo)控制視角轉(zhuǎn)動(dòng)
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)鼠標(biāo)控制視角轉(zhuǎn)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02C#利用iTextSharp組件給PDF文檔添加圖片/文字水印
這篇文章主要給大家介紹了關(guān)于如何C#利用iTextSharp組件給PDF文檔添加圖片/文字水印的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10Unity UGUI實(shí)現(xiàn)滑動(dòng)翻頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了Unity UGUI實(shí)現(xiàn)滑動(dòng)翻頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04