. net MAUI:使用MVVM时图形元素的动态行为



对于像进度条这样的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也是一样的,它应该每秒改变一次进度弧。

尝试使用DrawableStaticResource:

<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"/>

最新更新