【MAUI】自定义块状进度控件

文章目录

XAML

xml 复制代码
    <VerticalStackLayout>
        <Label x:Name="ProgressLable" TextColor="#A6FFFFFF" FontSize="14" Margin="26,0"></Label>
        <Grid x:Name="ProgressGrid" HorizontalOptions="Center" VerticalOptions="Center" Padding="0" BackgroundColor="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <!-- 动态生成列定义 -->
            </Grid.ColumnDefinitions>
            <CollectionView x:Name="Items" ItemsLayout="HorizontalList" Margin="0,4,0,32" >
                <CollectionView.ItemTemplate>
                    <DataTemplate>
                        <BoxView  CornerRadius="1" Grid.Row="0" Grid.Column="{Binding ColumnIndex}"
                             WidthRequest="{Binding BlockWidth}"
                             HeightRequest="{Binding BlockHeight}"
                             HorizontalOptions="Center" VerticalOptions="Center"
                             BackgroundColor="{Binding Color}" />
                    </DataTemplate>
                </CollectionView.ItemTemplate>
            </CollectionView>
        </Grid>
    </VerticalStackLayout>

.CS

csharp 复制代码
public partial class LumpProgressIndicator : ContentViewBase<LumpProgressIndicatorViewModel>
{
    public List<BlockItem> BlockItems { get; set; }
    public static double BlockWidth { get; set; }
    public static double BlockHeight { get; set; } = 6;
    public static double BlockSpacing { get; set; } = 5;

    public static double screenWidth { get; set; }
    public static double screenHeight { get; set; }
    public static double progressBarWidth { get; set; }

    public static int curIndexTemp { get; set; }
    #region 可绑定属性

    /// <summary>
    /// 当前进度
    /// </summary>
    public static readonly BindableProperty CurIndexProperty =
        BindableProperty.Create(
            propertyName: nameof(CurIndex),
            returnType: typeof(int),
            declaringType: typeof(LumpProgressIndicator),
            defaultBindingMode: BindingMode.TwoWay,
            propertyChanged: CurIndexPropertyChanged);

    public int CurIndex
    {
        get { return (int)base.GetValue(CurIndexProperty); }
        set { base.SetValue(CurIndexProperty, value); }
    }

    private static void CurIndexPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ReDraw((LumpProgressIndicator)bindable, oldValue, newValue, false);
    }

    /// <summary>
    /// 总数
    /// </summary>
    public static readonly BindableProperty CountProperty =
    BindableProperty.Create(
        propertyName: nameof(Count),
        returnType: typeof(int),
        declaringType: typeof(LumpProgressIndicator),
        defaultBindingMode: BindingMode.TwoWay,
        propertyChanged: CountPropertyChanged);

    public int Count
    {
        get { return (int)base.GetValue(CountProperty); }
        set { base.SetValue(CountProperty, value); }
    }

    private static void CountPropertyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        ReDraw((LumpProgressIndicator)bindable, oldValue, newValue, true);
    }
    #endregion
    private int currentQuestionIndex = 0;
    private int totalQuestions = 5;
    private List<BoxView> blockItems = new List<BoxView>();
    public LumpProgressIndicator()
    {
        CalculateBlockDimensions();
        InitializeComponent();
        //this.WhenActivated(d =>
        //{
        //    //this.OneWayBind(ViewModel, vm => vm.ReportVM, v => v.ReportPage.ViewModel).DisposeWith(d);
        //});

    }
    private void CalculateBlockDimensions()
    {
        // 计算每个块的宽度和高度
        screenWidth = App.Current.MainPage.Width;
        screenHeight = App.Current.MainPage.Height;
        // 假设进度条总宽度为屏幕宽度的 85%
        progressBarWidth = screenWidth * 0.85;
        // 设置块的高度
        BlockHeight = 6;
        BlockSpacing = 5;
    }
    public class BlockItem
    {
        public int ColumnIndex { get; set; }
        public double BlockWidth { get; set; }
        public double BlockHeight { get; set; }
        public string Color { get; set; }
    }
    public static int size = 1;
    private static void ReDraw(LumpProgressIndicator lumpProgressIndicator, object oldValue, object newValue, bool last)
    {
        //CurIndexPropertyChanged先执行CountPropertyChanged后执行
        if (!last)
        {
            curIndexTemp = (int)newValue;
        }
        else
        {
            LumpProgressIndicator.size = (int)newValue;
        }
        var value_new = (int)newValue;
        lumpProgressIndicator.ProgressLable.Text = $"当前进度({curIndexTemp.ToString()}/{LumpProgressIndicator.size.ToString()})";
        lumpProgressIndicator.ProgressLable.Margin = new Thickness(left: progressBarWidth * 0.07 - BlockSpacing, top: 0, right: 0, bottom: 5);
        // 每个块的宽度为进度条总宽度减去所有间隔后除以块的数量 
        BlockWidth = (progressBarWidth -  BlockSpacing) / LumpProgressIndicator.size;
        int size = LumpProgressIndicator.size * 2 - 1;
        for (int i = 0; i < size; i++)
        {
            lumpProgressIndicator.ProgressGrid.ColumnDefinitions.Add(
                            new ColumnDefinition { Width = GridLength.Auto }
                );
        }

        List<BlockItem> BlockItems = new List<BlockItem>();
        int loop = LumpProgressIndicator.size * 2 - 1;
        for (int i = 1; i <= loop; i++)
        {
            BlockItem temp = new BlockItem();
            temp.ColumnIndex = i - 1;
            temp.BlockHeight = BlockHeight;

            if (i % 2 == 0)
            {
                temp.BlockWidth = BlockSpacing;
                temp.Color = "Transparent";
            }
            else
            {
                int index_temp = curIndexTemp * 2 - 1;
                if (i > index_temp)
                {
                    temp.BlockWidth = BlockWidth;
                    temp.Color = "#FF3C3E58";
                }
                else
                {
                    temp.BlockWidth = BlockWidth;
                    temp.Color = "#FF6E73FF";
                }
            }
            BlockItems.Add(temp);
        }
        lumpProgressIndicator.Items.ItemsSource = BlockItems;
    }
}

使用

xml 复制代码
<view:LumpProgressIndicator CurIndex="1" x:Name="lumpProgressIndicator" Count="6" Margin="0,20,0,8"></view:LumpProgressIndicator>
相关推荐
zxy28472253011 天前
.NET MAUI教程2-利用.NET CommunityToolkit.Maui框架弹Toast
c#·.net·maui·toolkit.maui
初级代码游戏1 个月前
MAUI(C#)安卓开发起步
android·开发语言·c#·hyper-v·maui·haxm·aehd
花北城1 个月前
【Maui】自定义统一色彩样式
maui·颜色
时光追逐者2 个月前
推荐几款开源免费的 .NET MAUI 组件库
microsoft·开源·c#·.net·.net core·maui
林晓lx2 个月前
开箱即用的.NET MAUI组件库 V-Control 发布了!
c#·.net·maui
林晓lx2 个月前
V-Control 开箱即用的.NET MAUI组件库发布了!
.net·maui
飞人博尔特的摄影师5 个月前
WPF绑定Bind方法合集,实时更新
visualstudio·c#·wpf·xaml·maui·xamarin·技巧
zzlyx995 个月前
采用abp框架进行maui开发,启动页面时如何新增后台服务
maui·maui手机端开发