Xamarin.forms 如何使用带有动态时间的ProgressRing xamarin窗体显示计时器

Xamarin.forms 如何使用带有动态时间的ProgressRing xamarin窗体显示计时器,xamarin.forms,Xamarin.forms,我已经使用引用的代码实现了一个带有时间的进度环 现在我想动态地绑定totaltime的值,这样当时间达到某个固定值时,进度环就开始进行。如何实现这一点?由于ConverterParameter不是可绑定的属性,因此我们不能使用绑定。但是我们可以尝试使用bindable属性自定义此标签,并将其自身传递给转换器参数 自定义此标签,如: public class MyLabel : Label { public double TotalTime { set { SetV

我已经使用引用的代码实现了一个带有时间的进度环


现在我想动态地绑定totaltime的值,这样当时间达到某个固定值时,进度环就开始进行。如何实现这一点?

由于
ConverterParameter
不是可绑定的属性,因此我们不能使用
绑定。但是我们可以尝试使用bindable属性自定义此标签,并将其自身传递给
转换器参数

自定义此标签,如:

public class MyLabel : Label
{
    public double TotalTime
    {
        set { SetValue(TotalTimeProperty, value); }
        get { return (double)GetValue(TotalTimeProperty); }
    }
    public static readonly BindableProperty TotalTimeProperty = BindableProperty.Create(nameof(TotalTime), typeof(double), typeof(MyLabel), default(double));
}
<local:MyLabel x:Name="MyLabel" 
                TotalTime="{Binding TotalTime}"
                Text="{Binding Source={x:Reference progressBar}, Path=Progress, Converter={StaticResource countDownTime}, ConverterParameter={x:Reference MyLabel}"
                HorizontalOptions ="Center"
                FontSize="20"
                FontFamily = "Helvetica Neue"
                TextColor = "Red" />
public class BindModel : INotifyPropertyChanged
{
    double totalTime;
    public double TotalTime
    {
        set
        {
            totalTime = value;
            onPropertyChanged("TotalTime");
        }
        get
        {
            return totalTime;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void onPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
// And set this model as a BindingContext 
var model = new BindModel { TotalTime = 60000 };
BindingContext = model;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    double time = 0;
    double myTotalTime = ((MyLabel)parameter).TotalTime;
    double.TryParse(myTotalTime.ToString(), out var totalTime);
    double.TryParse(value.ToString(), out var progress);
    time = progress <= double.Epsilon ? totalTime : (totalTime - (totalTime * progress));
    var timeSpan = TimeSpan.FromMilliseconds(time);
    return $"{timeSpan.Minutes:00;00}:{timeSpan.Seconds:00;00}";
}
然后我们可以在XAML中传递自身:

public class MyLabel : Label
{
    public double TotalTime
    {
        set { SetValue(TotalTimeProperty, value); }
        get { return (double)GetValue(TotalTimeProperty); }
    }
    public static readonly BindableProperty TotalTimeProperty = BindableProperty.Create(nameof(TotalTime), typeof(double), typeof(MyLabel), default(double));
}
<local:MyLabel x:Name="MyLabel" 
                TotalTime="{Binding TotalTime}"
                Text="{Binding Source={x:Reference progressBar}, Path=Progress, Converter={StaticResource countDownTime}, ConverterParameter={x:Reference MyLabel}"
                HorizontalOptions ="Center"
                FontSize="20"
                FontFamily = "Helvetica Neue"
                TextColor = "Red" />
public class BindModel : INotifyPropertyChanged
{
    double totalTime;
    public double TotalTime
    {
        set
        {
            totalTime = value;
            onPropertyChanged("TotalTime");
        }
        get
        {
            return totalTime;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void onPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
// And set this model as a BindingContext 
var model = new BindModel { TotalTime = 60000 };
BindingContext = model;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    double time = 0;
    double myTotalTime = ((MyLabel)parameter).TotalTime;
    double.TryParse(myTotalTime.ToString(), out var totalTime);
    double.TryParse(value.ToString(), out var progress);
    time = progress <= double.Epsilon ? totalTime : (totalTime - (totalTime * progress));
    var timeSpan = TimeSpan.FromMilliseconds(time);
    return $"{timeSpan.Minutes:00;00}:{timeSpan.Seconds:00;00}";
}
您的IValueConverter也应该是这样的:

public class MyLabel : Label
{
    public double TotalTime
    {
        set { SetValue(TotalTimeProperty, value); }
        get { return (double)GetValue(TotalTimeProperty); }
    }
    public static readonly BindableProperty TotalTimeProperty = BindableProperty.Create(nameof(TotalTime), typeof(double), typeof(MyLabel), default(double));
}
<local:MyLabel x:Name="MyLabel" 
                TotalTime="{Binding TotalTime}"
                Text="{Binding Source={x:Reference progressBar}, Path=Progress, Converter={StaticResource countDownTime}, ConverterParameter={x:Reference MyLabel}"
                HorizontalOptions ="Center"
                FontSize="20"
                FontFamily = "Helvetica Neue"
                TextColor = "Red" />
public class BindModel : INotifyPropertyChanged
{
    double totalTime;
    public double TotalTime
    {
        set
        {
            totalTime = value;
            onPropertyChanged("TotalTime");
        }
        get
        {
            return totalTime;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    void onPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
// And set this model as a BindingContext 
var model = new BindModel { TotalTime = 60000 };
BindingContext = model;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    double time = 0;
    double myTotalTime = ((MyLabel)parameter).TotalTime;
    double.TryParse(myTotalTime.ToString(), out var totalTime);
    double.TryParse(value.ToString(), out var progress);
    time = progress <= double.Epsilon ? totalTime : (totalTime - (totalTime * progress));
    var timeSpan = TimeSpan.FromMilliseconds(time);
    return $"{timeSpan.Minutes:00;00}:{timeSpan.Seconds:00;00}";
}
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性) { 双倍时间=0; double myTotalTime=((MyLabel)参数).TotalTime; double.TryParse(myTotalTime.ToString(),out var totalTime); double.TryParse(value.ToString(),out var progress); 时间=进度