C# WinForm自定义进度条

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# WinForm自定义进度条相关的知识,希望对你有一定的参考价值。

现在有两个窗口,一个主窗口和一个模态窗口,想根据主窗口里的datatable的数据加载情况,来控制模态窗口的进度条显示,不需要显示百分比的数据,只需要datatable数据加载完毕后,使模态窗口关闭即可,如用多线程如何实现,还有就是模态窗口如何屏蔽在windows状态栏下的关闭状态(如图),虽然进度在显示加载中,但是可以直接通过windows状态栏直接关闭模态窗口,不管数据加载是否完成
最好能有代码实例参考

参考技术A

 单线程程序: 开始加载datatable数据前创建FrmWait   加载完后关闭。

 //判断是否存在该窗口
  FrmWait newFrmWait = new FrmWait();
 bool IsExist =False;
 foreach (Form f in Application.OpenForms)

      if (f.GetType() == typeof(FrmWait))
       
           IsExist =trune;
           // 这里添加处理  关闭??
           break;
        
 
 //如果等待界面不存在  启动等待界面
 if(!IsExist)
 
    newFrmWait.ShowDialog(); 
 
 
  //这里加载datatable
  foreach (Form f in Application.OpenForms)

      if (f.GetType() == typeof(FrmWait))
       
        //关闭等待界面
           f.Close();
          
           break;
        
 

追问

你的方法实现不了,模态窗口打开,数据不加载

追答

哦哦 你把 newFrmWait.ShowDialog();
改为 newFrmWait.Show();

追问

这样也有一个缺点就是,在显示加载数据时,主界面上的其他按钮还是可以点击的,这样做用户体验不好

追答

那你可以把加载datatable放到 FrmWait 里  等加载好就关闭,让后在调用窗口将数据取出来;

FrmWait newFrmWait = new FrmWait(type  datat/*加载datatable 所需的条件*/);

newFrmWait.ShowDialog(); 

data = newFrmWait.myTable;

 要注意没加载好关闭FrmWait 的情况

参考技术B 把那个模态窗口的 ShowInTaskbar 设置为 false 不就不在任务栏上显示了么…… 参考技术C 为什么要用这么麻烦的modal+多线程,

this.Enabled = false;
FrmWait.ShowInTaskbar = false;
FrmWait.Show(this);

不行么?追问

主界面在加载数据,模态窗口显示正在加载数据,主界面数据加载完毕,模态窗口就关闭,这样不会让用户觉得界面卡死,不用多线程如何实现?

追答

用模态就要上多线程不然会卡死加载,如下面的那个。我这个方法禁掉this也就是Form1的使用,同时显示Frmwait显示正在加载数据。加载数据部分写在FrmWait.Show(this);之后。在读取完成后由Form1关闭Frmwait即可。必要的话加Application.Doevents();,要在Frmwait里显示动画也不难。还有你那个稍候字写错了,为啥连商业游戏都有写错成稍后的

本回答被提问者和网友采纳

C# 自定义控件(圆形进度条) Xamarin Forms

【中文标题】C# 自定义控件(圆形进度条) Xamarin Forms【英文标题】:C# custom control (circle progress bar) Xamarin Forms 【发布时间】:2016-09-19 16:15:35 【问题描述】:

我想知道用 Xamarin Forms 创建与此图像类似的东西的最佳方法:

我从来没有创造过这样的东西。我知道如何使用进度条,但不知道“圆形进度条”

感谢您的帮助和任何提示。

编辑:如果你有一个插件/nuget 来做到这一点,那很酷,但我想知道如何自己做。我从来没有做过这样的事情。

【问题讨论】:

你有iOS和Android的解决方案吗? 【参考方案1】:

My Trip Countdown 是一个 Xamarin.Forms 示例,用于展示如何使用 Xamarin.Forms 创建美观的 UI。此示例基于 Victoria Sgarro 设计的倒数计时器。

给你:https://github.com/jsuarezruiz/MyTripCountdown

【讨论】:

【参考方案2】:

我知道这是一篇旧帖子,但是像我这样的人在我们搜索循环进度时得到了这个帖子。

Andreas Hennig 做了一个不错的插件,适用于 iOS 和 Android,你可以从 nuget 安装它:Progress Ring Control Plugin

XAML

    添加 XAML 命名空间:

    xmlns:control="clr-namespace:ProgressRingControl.Forms.Plugin;assembly=ProgressRing.Forms.Plugin"

    添加 xaml:

    <control:ProgressRing RingThickness="20" Progress="0.5"/>

您可以在以下位置找到它:

https://github.com/AndreasHennig/ProgressRingPlugin

【讨论】:

ProgressRing中间如何显示进度条的数量?【参考方案3】:

您可以使用自定义渲染器实现此目的。

Xamarin 的 James Montemagno 对创建自定义圆形进度条有很好的指导。

https://devblogs.microsoft.com/xamarin/using-custom-controls-in-xamarin-forms-on-android/

有关 Xamarin.Forms 自定义渲染器的官方文档可在以下位置找到 https://developer.xamarin.com/guides/xamarin-forms/custom-renderer/

【讨论】:

我喜欢 James Montemagno 教程,但渲染器仅适用于 Android。我也想为IOS做点什么 你的问题是关于如何创建循环进度条,解决方案是使用“自定义渲染器”任何你可以使用components.xamarin.com/gettingstarted/radialprogress组件的方式 你知道有没有办法为 uwp 完成这个? @AbdulMuhaymin Radialprogress 用于本地解决方案,不是吗。问题是针对应该支持 iOS、Android 的 Xamarin Forms。【参考方案4】:

我发现 this post 是迄今为止 Xamarin Forms“圆形进度条”的最佳解决方案。基本上,您使用两个半圆形图像并根据进度旋转它们,我认为这是一个非常有创意和优雅的解决方案。无需自定义渲染器!

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。 这里的代码仍然可用github.com/billreiss/xamlnative/tree/master/XamarinForms/…【参考方案5】:

我尝试为 Xamarin Forms 找到一个库,但找不到任何同时支持 Android 和 iOS 的库。此外,从不同类型的进度指标中可供选择的选择并不多。我最终使用支持 Android 和 iOS 的 SkiaSharp 在 Xamarin Forms 中构建了我自己的自定义径向进度指示器小部件。

教程链接:https://medium.com/@kpshinde25/custom-radial-progress-indicator-in-xamarin-forms-c7ed81840c1e

您可以根据您的要求修改代码以具有圆形、多圆形指示器等。

【讨论】:

【参考方案6】:

来自https://github.com/billreiss/xamlnative/tree/master/XamarinForms/CircularProgress的代码

public class CircularProgress : Grid

    View progress1;
    View progress2;
    View background1;
    View background2;
    public CircularProgress()
    
        var baseUrl = "https://github.com/billreiss/xamlnative/raw/master/XamarinForms/CircularProgress/CircularProgress/CircularProgress.Droid/Resources/drawable/";
        
        progress1 = CreateImage($"baseUrlprogress_done.png");
        background1 = CreateImage($"baseUrlprogress_pending.png");
        background2 = CreateImage($"baseUrlprogress_pending.png");
        progress2 = CreateImage($"baseUrlprogress_done.png");
        HandleProgressChanged(1, 0);
    

    private View CreateImage(string imageName)
    
        var img = new Image();
        img.Source = ImageSource.FromUri(new Uri(imageName));
        this.Children.Add(img);
        return img;
    

    public static BindableProperty ProgressProperty =
BindableProperty.Create(nameof(Progress), typeof(double), typeof(CircularProgress), 0d, propertyChanged: ProgressChanged);

    private static void ProgressChanged(BindableObject bindable, object oldValue, object newValue)
    
        var c = bindable as CircularProgress;
        c.HandleProgressChanged(Clamp((double)oldValue, 0, 1), Clamp((double)newValue, 0, 1));
    

    static double Clamp(double value, double min, double max)
    
        if (value <= max && value >= min) return value;
        else if (value > max) return max;
        else return min;
    

    private void HandleProgressChanged(double oldValue, double p)
    
        if (p < .5)
        
            if (oldValue >= .5)
            
                // this code is CPU intensive so only do it if we go from >=50% to <50%
                background1.IsVisible = true;
                progress2.IsVisible = false;
                background2.Rotation = 180;
                progress1.Rotation = 0;
            
            double rotation = 360 * p;
            background1.Rotation = rotation;
        
        else
        
            if (oldValue < .5)
            
                // this code is CPU intensive so only do it if we go from <50% to >=50%
                background1.IsVisible = false;
                progress2.IsVisible = true;
                progress1.Rotation = 180;
            
            double rotation = 360 * p;
            background2.Rotation = rotation;
        
    

    public double Progress
    
        get  return (double)this.GetValue(ProgressProperty); 
        set  SetValue(ProgressProperty, value); 
    

【讨论】:

以上是关于C# WinForm自定义进度条的主要内容,如果未能解决你的问题,请参考以下文章

C# Winform 想做一个CSV传入数据库的进度条,怎么做?

重写C# winform 进度条的样式(要代码示例)

c#中 progressbar 进度条控件怎么开始???

C# winform加载子窗体很慢 如何用进度条显示

(四十一)c#Winform自定义控件-进度条

(四十六)c#Winform自定义控件-水波进度条