对于像进度条这样的UI元素的动画,即使在微软文档中,也总是有建议(只)从后面的代码中工作,像这样:
await progressBar.ProgressTo(0.75, 500, Easing.Linear);
我找不到一种方法来做到这一点,从ViewModel,因为它是不可能的(也不打算)访问XAML元素从那里。我尝试用数据绑定,使用BindableProperty。不能让它工作。那么,是我的想法错了,还是根本不可能?
我创建了一个Drawable类:public class ProgressArcDrawable : GraphicsView, IDrawable
{
public double ArcProgress
{
get => (double)GetValue(ArcProgressProperty);
set => SetValue(ArcProgressProperty, value);
}
public float Stroke
{
get => (float)GetValue(StrokeProperty);
set => SetValue(StrokeProperty, value);
}
public Color ArcColor
{
get => (Color)GetValue(ArcColorProperty);
set => SetValue(ArcColorProperty, value);
}
public static readonly BindableProperty ArcProgressProperty =
BindableProperty.Create(nameof(ArcProgress), typeof(double), typeof(ProgressArcDrawable));
public static readonly BindableProperty StrokeProperty =
BindableProperty.Create(nameof(Stroke), typeof(float), typeof(ProgressArcDrawable));
public static readonly BindableProperty ArcColorProperty =
BindableProperty.Create(nameof(ArcColor), typeof(Color), typeof(ProgressArcDrawable));
public void Draw(ICanvas canvas, RectF dirtyRect)
{
var endAngle = 90 - (int)Math.Round(ArcProgress * 360, MidpointRounding.AwayFromZero);
canvas.StrokeColor = ArcColor;
canvas.StrokeSize = Stroke;
canvas.DrawArc(Stroke / 2, Stroke / 2, (dirtyRect.Width - Stroke), (dirtyRect.Height - Stroke), 90, endAngle, false, false);
}
}
当我使用MVVM工具包时,我在我的视图模型中创建了ObservableProperties,如下所示:
[ObservableProperty]
double arcProgress;
在我看来,我将drawable与数据绑定集成在一起:
<ContentPage.Resources>
<drawables:ProgressArcDrawable
x:Key="progressArcDrawable"
ArcProgress="{Binding ArcProgress}"
Stroke="20"
ArcColor="{Binding Scrum.ScrumTheme.AccentColor}" />
</ContentPage.Resources>
...
<Grid>
<GraphicsView
Drawable="{StaticResource progressArcDrawable}"
HeightRequest="350"
WidthRequest="350" />
</Grid>
唯一有效的绑定是将笔画设置为离散值的绑定。AccentColor绑定适用于页面上的其他元素,因此那里有数据,但它不适用于drawable。这对于ArcProgress也是一样的,它应该每秒改变一次进度弧。
尝试使用Drawable
和StaticResource
:
<Grid>
<GraphicsView
HeightRequest="350"
WidthRequest="350">
<GraphicsView.Drawable>
<drawables:ProgressArcDrawable
ArcProgress="{Binding ArcProgress}"
Stroke="20"
ArcColor="{Binding Scrum.ScrumTheme.AccentColor}" />
</GraphicsView.Drawable>
</GraphicsView>
</Grid>
如果你还在寻找这个,下面是我的做法。
public class ProgressArcDrawable : GraphicsView, IDrawable
{
public ProgressArcDrawable()
{
Drawable = this;
}
//...
}
XAML文件
<local:ProgressArcDrawable ArcProgress ="{Binding ProgressValue}"
HeightRequest="50" WidthRequest="50"/>