最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF實(shí)現(xiàn)自繪儀表盤(pán)Gauge

 更新時(shí)間:2024年12月31日 10:12:42   作者:WPF開(kāi)發(fā)者  
這篇文章主要為大家詳細(xì)介紹了如何使用WPF實(shí)現(xiàn)自繪儀表盤(pán)Gauge效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

自繪儀表盤(pán) Gauge

框架支持.NET4 至 .NET8;

Visual Studio 2022;

WPFDevelopers 1.1.0.3-preview 版本已正式發(fā)布!

該版本為預(yù)覽版,歡迎各位開(kāi)發(fā)者下載并體驗(yàn)。

來(lái)自 Issue

邏輯實(shí)現(xiàn)

Gauge 繼承 RangeBase,支持設(shè)置最大值、最小值以及當(dāng)前值,并且可以顯示一個(gè)動(dòng)態(tài)的百分比值、標(biāo)題、刻度。

1. 新增 Gauge.cs

依賴(lài)屬性

  • Title:儀表盤(pán)的標(biāo)題,默認(rèn)值為 "WD"。
  • ValueFormat:定義數(shù)值顯示的格式( {0:0}%),以百分比形式顯示當(dāng)前值。
  • Thickness:設(shè)置儀表盤(pán)的邊框,默認(rèn)值 10。
public string Title
{
    get { return (string)GetValue(TitleProperty); }
    set { SetValue(TitleProperty, value); }
}
 public string ValueFormat
 {
     get { return (string)GetValue(ValueFormatProperty); }
     set { SetValue(ValueFormatProperty, value); }
 }
 public double Thickness
 {
     get { return (double)GetValue(ThicknessProperty); }
     set { SetValue(ThicknessProperty, value); }
 }

RangeBase 依賴(lài)屬性

  • Value:設(shè)置為 0.0,表示當(dāng)前的儀表盤(pán)值(默認(rèn) 0%)。
  • Minimum:設(shè)置為 0.0,表示儀表盤(pán)的最小值。
  • Maximum:設(shè)置為 100.0,表示儀表盤(pán)的最大值。
public Gauge()
{
    SetValue(ValueProperty, 0.0);
    SetValue(MinimumProperty, 0.0);
    SetValue(MaximumProperty, 100.0);
}

2. 重寫(xiě) OnRender 方法繪制控件

背景:使用 Ellipse 作為儀表盤(pán)的背景,背景色通過(guò) Background 屬性設(shè)置,默認(rèn)為 #293950。

指針:根據(jù)當(dāng)前值(Value),計(jì)算出指針的角度,并使用 DrawLine 繪制紅色指針。

外邊框:使用漸變顏色繪制儀表盤(pán)的外邊框。

刻度和標(biāo)簽:繪制了從最小值到最大值的刻度線,并在每個(gè)刻度繪制了對(duì)應(yīng)的刻度值。

當(dāng)前值顯示:根據(jù) ValueFormat 屬性格式化顯示當(dāng)前值,并顯示在儀表盤(pán)的底部位置。

protected override void OnRender(DrawingContext drawingContext)
{
    base.OnRender(drawingContext);
    if (Background == null)
        Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#293950"));
    var width = ActualWidth;
    var height = ActualHeight;
    var radius = Math.Min(width, height) / 2;
    drawingContext.DrawEllipse(Background, new Pen(Background, Thickness), new Point(width / 2, height / 2), radius, radius);
    var normalizedValue = (Value - Minimum) / (Maximum - Minimum);
    var mappedAngle = -220 + normalizedValue * 260;
    var angleInRadians = mappedAngle * Math.PI / 180;
    var pointerLength = radius * 0.7;
    var pointerX = width / 2 + pointerLength * Math.Cos(angleInRadians);
    var pointerY = height / 2 + pointerLength * Math.Sin(angleInRadians);
    drawingContext.DrawLine(new Pen(Brushes.Red, 2), new Point(width / 2, height / 2), new Point(pointerX, pointerY));
    drawingContext.DrawEllipse(Brushes.White, new Pen(Brushes.Red, 2), new Point(width / 2, height / 2), width / 20, width / 20);
    var pathGeometry = new PathGeometry();
    var startAngle = -220;
    angleInRadians = startAngle * Math.PI / 180;
    var startX = width / 2 + radius * Math.Cos(angleInRadians);
    var startY = height / 2 + radius * Math.Sin(angleInRadians);

    var pathFigure = new PathFigure()
    {
        StartPoint = new Point(startX, startY),
    };

    var endAngle = 40;
    angleInRadians = endAngle * Math.PI / 180;
    var endX = width / 2 + radius * Math.Cos(angleInRadians);
    var endY = height / 2 + radius * Math.Sin(angleInRadians);

    var isLargeArc = (endAngle - startAngle > 180);
    var arcSegment = new ArcSegment()
    {
        Point = new Point(endX, endY),
        Size = new Size(radius, radius),
        RotationAngle = 0,
        SweepDirection = SweepDirection.Clockwise,
        IsLargeArc = isLargeArc,
    };

    pathFigure.Segments.Add(arcSegment);
    pathGeometry.Figures.Add(pathFigure);
    if (BorderBrush == null)
    {
        var gradientBrush = new LinearGradientBrush
        {
            StartPoint = new Point(0, 0),
            EndPoint = new Point(1, 0)
        };
        gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#37D2C2"), 0.0));
        gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#5AD2B2"), 0.01));
        gradientBrush.GradientStops.Add(new GradientStop((Color)ColorConverter.ConvertFromString("#B77D29"), 0.49));
        gradientBrush.GradientStops.Add(new GradientStop(Colors.Red, 1.0));
        gradientBrush.Freeze();
        BorderBrush = gradientBrush;
    }
    drawingContext.DrawGeometry(null, new Pen(BorderBrush, Thickness), pathGeometry);
    var tickLength = radius * 0.1; 
    var step = (Maximum - Minimum) / 10;
    for (int i = 0; i <= 10; i++)
    {
        var angle = startAngle + (i * (endAngle - startAngle) / 10);
        var tickStartX = width / 2 + (radius - tickLength) * Math.Cos(angle * Math.PI / 180);
        var tickStartY = height / 2 + (radius - tickLength) * Math.Sin(angle * Math.PI / 180);
        var tickEndX = width / 2 + (radius + Thickness / 2) * Math.Cos(angle * Math.PI / 180);
        var tickEndY = height / 2 + (radius + Thickness / 2) * Math.Sin(angle * Math.PI / 180);
        drawingContext.DrawLine(new Pen(Brushes.White, 2), new Point(tickStartX, tickStartY), new Point(tickEndX, tickEndY));

        var labelValue = Minimum + step * i;
        var formattedText = DrawingContextHelper.GetFormattedText(labelValue.ToString(),Brushes.White, FlowDirection.LeftToRight,FontSize);

        var labelRadius = radius - tickLength * 2;
        var labelX = width / 2 + labelRadius * Math.Cos(angle * Math.PI / 180) - formattedText.Width / 2;
        var labelY = height / 2 + labelRadius * Math.Sin(angle * Math.PI / 180) - formattedText.Height / 2;
        drawingContext.DrawText(formattedText, new Point(labelX, labelY));
    }
    var formattedValue = "{0:0}%";
    try
    {
        formattedValue = string.Format(ValueFormat, Value);
    }
    catch (FormatException ex)
    {
        throw new InvalidOperationException("Formatting failed ", ex);
    }
    var currentValueText = DrawingContextHelper.GetFormattedText(formattedValue, Brushes.White, FlowDirection.LeftToRight, FontSize * 2);
    var valueX = width / 2 - currentValueText.Width / 2;
    var valueY = height / 2 + radius * 0.4; 
    drawingContext.DrawText(currentValueText, new Point(valueX, valueY));
    var titleValue = DrawingContextHelper.GetFormattedText(Title, Brushes.White, FlowDirection.LeftToRight, FontSize);
    valueX = width / 2 - titleValue.Width / 2;
    valueY = height / 2 + radius * 0.8;
    drawingContext.DrawText(titleValue, new Point(valueX, valueY));
}

XAML 示例

示例引入 WPFDevelopers 1.1.0.3-preview 的 Nuget 正式包

<WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center">
    <StackPanel VerticalAlignment="Bottom">
        <wd:Gauge
            Title="Min"
            Width="100"
            Height="100"
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Background="Black"
            BorderBrush="Red"
            FontSize="8"
            Maximum="90"
            Minimum="30"
            Thickness="3"
            ValueFormat="{}{0:0}值"
            Value="{Binding ElementName=MySlider2, Path=Value}" />
        <Slider
            Name="MySlider2"
            Width="200"
            Margin="0,0,0,20"
            HorizontalAlignment="Center"
            VerticalAlignment="Bottom"
            Maximum="90"
            Minimum="30" />
    </StackPanel>

    <StackPanel>
        <wd:Gauge
            Title="反對(duì)率"
            Width="200"
            Height="200"
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            ValueFormat="{}{0:0}%"
            Value="{Binding ElementName=MySlider, Path=Value}" />
        <Slider
            Name="MySlider"
            Width="200"
            Margin="0,0,0,20"
            HorizontalAlignment="Center"
            VerticalAlignment="Bottom"
            Maximum="100"
            Minimum="0" />
    </StackPanel>
    <StackPanel VerticalAlignment="Bottom">
        <wd:Gauge
            Title="Max"
            Width="100"
            Height="100"
            Margin="10"
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            Background="Black"
            BorderBrush="DodgerBlue"
            FontSize="8"
            Maximum="90"
            Minimum="30"
            Thickness="3"
            ValueFormat="{}{0:0}值"
            Value="{Binding ElementName=MySlider3, Path=Value}" />
        <Slider
            Name="MySlider3"
            Width="200"
            Margin="0,0,0,20"
            HorizontalAlignment="Center"
            VerticalAlignment="Bottom"
            Maximum="90"
            Minimum="30" />
    </StackPanel>
</WrapPanel>

效果圖

到此這篇關(guān)于WPF實(shí)現(xiàn)自繪儀表盤(pán)Gauge的文章就介紹到這了,更多相關(guān)WPF自繪儀表盤(pán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#無(wú)邊框窗體實(shí)現(xiàn)以及拖動(dòng)代碼

    C#無(wú)邊框窗體實(shí)現(xiàn)以及拖動(dòng)代碼

    我們給大家分享了關(guān)于C#無(wú)邊框窗體實(shí)現(xiàn)以及拖動(dòng)代碼,大家在程序設(shè)計(jì)的時(shí)候如果用的到一起跟著小編學(xué)習(xí)下吧。
    2018-03-03
  • C#借助Spire.Doc for .NET實(shí)現(xiàn)Word段落和文本添加底紋

    C#借助Spire.Doc for .NET實(shí)現(xiàn)Word段落和文本添加底紋

    在日常的 Word 文檔處理中,我們經(jīng)常需要通過(guò)各種視覺(jué)手段來(lái)突出重點(diǎn)信息,本文將深入探討如何利用Spire.Doc for .NET實(shí)現(xiàn) Word 段落和文本的底紋效果,感興趣的小伙伴可以了解下
    2026-02-02
  • C#中ExcelDataReader的具體使用

    C#中ExcelDataReader的具體使用

    ExcelDataReader是一個(gè)輕量級(jí)的可快速讀取Excel文件中數(shù)據(jù)的工具,本文主要介紹了C#中ExcelDataReader的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-04-04
  • C#?中的多態(tài)底層虛方法調(diào)用詳情

    C#?中的多態(tài)底層虛方法調(diào)用詳情

    這篇文章主要介紹了C#?中的多態(tài)底層虛方法調(diào)用詳情,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,需要的小伙伴你可以參考一下
    2022-06-06
  • 使用C#實(shí)現(xiàn)AES加密與解密的示例

    使用C#實(shí)現(xiàn)AES加密與解密的示例

    在現(xiàn)代應(yīng)用程序中,數(shù)據(jù)加密是保護(hù)敏感信息安全的重要手段,AES(高級(jí)加密標(biāo)準(zhǔn))是一種廣泛使用的對(duì)稱(chēng)加密算法,提供強(qiáng)大的數(shù)據(jù)保護(hù)功能,今天,我將為大家展示如何使用 C# 實(shí)現(xiàn) AES 加密和解密,需要的朋友可以參考下
    2024-12-12
  • C#用websocket實(shí)現(xiàn)簡(jiǎn)易聊天功能(客戶(hù)端)

    C#用websocket實(shí)現(xiàn)簡(jiǎn)易聊天功能(客戶(hù)端)

    這篇文章主要為大家詳細(xì)介紹了C#用websocket實(shí)現(xiàn)簡(jiǎn)易聊天功能,客戶(hù)端方向,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • c#開(kāi)發(fā)的程序安裝時(shí)動(dòng)態(tài)指定windows服務(wù)名稱(chēng)

    c#開(kāi)發(fā)的程序安裝時(shí)動(dòng)態(tài)指定windows服務(wù)名稱(chēng)

    前段時(shí)間由于項(xiàng)目的需求,要在Windows里把同樣的組件制作成多個(gè)不同名稱(chēng)的服務(wù),這些服務(wù)完成類(lèi)似的功能,僅需要修改業(yè)務(wù)配置文件
    2012-06-06
  • VS?Code里使用Debugger?for?Unity插件調(diào)試的方法(2023最新版)

    VS?Code里使用Debugger?for?Unity插件調(diào)試的方法(2023最新版)

    Debugger for Unity是一個(gè)非正式支持的,官方推薦的,應(yīng)用最廣的,Visual Studio Code上的Unity調(diào)試插件,這篇文章主要介紹了VS?Code里使用Debugger?for?Unity插件進(jìn)行調(diào)試(2023最新版),需要的朋友可以參考下
    2023-02-02
  • C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁(yè)詳解

    C#使用CefSharp實(shí)現(xiàn)內(nèi)嵌網(wǎng)頁(yè)詳解

    這篇文章主要介紹了C# WPF里怎么使用CefSharp嵌入一個(gè)網(wǎng)頁(yè),并給出一個(gè)簡(jiǎn)單示例演示C#和網(wǎng)頁(yè)(JS)的交互實(shí)現(xiàn),感興趣的小伙伴可以了解一下
    2023-04-04
  • C#定時(shí)器組件FluentScheduler用法

    C#定時(shí)器組件FluentScheduler用法

    這篇文章介紹了C#定時(shí)器插件FluentScheduler的用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

沂水县| 临泉县| 秦安县| 太保市| 梨树县| 绥宁县| 酒泉市| 旅游| 乐清市| 曲沃县| 铁岭市| 德安县| 剑川县| 永靖县| 兴化市| 房产| 岢岚县| 扎兰屯市| 玉树县| 永吉县| 香河县| 黄骅市| 凤台县| 万州区| 开远市| 剑川县| 丰原市| 封开县| 甘泉县| 浦北县| 吉安市| 鄂伦春自治旗| 张家口市| 沙雅县| 临安市| 万宁市| 聊城市| 同德县| 宜兴市| 绥江县| 峡江县|