You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中View与GraphicsView属性绑定问题求助

MAUI中Slider绑定GraphicsView自定义Drawable属性的解决方案

问题场景

在MainPage中添加Slider控件,通过其值控制GraphicsView画布上绘制图形的高度,尝试将Slider的值绑定到ViewModel的Hayt属性,再将该属性绑定到自定义Drawable类CustomChart的Grid_Height属性时,出现错误提示:未找到"Grid_Height"的属性、可绑定属性或事件,或值与属性类型不匹配。

错误原因

  1. 类继承逻辑错误:CustomChart同时继承GraphicsView并实现IDrawable,但GraphicsView是UI显示控件,IDrawable是绘制逻辑载体,二者职责应分离;且非BindableObject子类的自定义类无法正确识别可绑定属性。
  2. ViewModel代码不规范:Hayt属性的setter未用大括号包裹代码块,导致无论值是否变化都会执行赋值和通知,不符合MVVM规范。
  3. 缺失重绘触发机制:属性值变化时未通知GraphicsView执行重绘,即使绑定成功也无法实时更新图形。

修复步骤

1. 重构自定义Drawable类

让CustomChart继承BindableObject并实现IDrawable,正确定义可绑定属性:

internal class CustomChart : BindableObject, IDrawable
{
    readonly float ScreenWidth = (float)DeviceDisplay.MainDisplayInfo.Width;
    readonly float ScreenHeight = (float)DeviceDisplay.MainDisplayInfo.Height;
    readonly float Density = (float)DeviceDisplay.MainDisplayInfo.Density;

    public static readonly BindableProperty Grid_HeightProperty = BindableProperty.Create(
        nameof(Grid_Height),
        typeof(double),
        typeof(CustomChart),
        0.7d);

    public double Grid_Height
    {
        get => (double)GetValue(Grid_HeightProperty);
        set => SetValue(Grid_HeightProperty, value);
    }

    public void Draw(ICanvas canvas, RectF dirtyRect)
    {
        float Y_Top = dirtyRect.Top;
        float Y_Bot = dirtyRect.Bottom / Density * (float)Grid_Height;
        float X_Right = dirtyRect.Right / Density;
        float X_Left = dirtyRect.Left;

        // 示例绘制逻辑:绘制蓝色边框矩形
        canvas.StrokeColor = Colors.Blue;
        canvas.StrokeSize = 2;
        canvas.DrawRectangle(X_Left, Y_Top, X_Right - X_Left, Y_Bot - Y_Top);
    }
}

2. 修正ViewModel属性逻辑

完善Hayt属性的setter代码块,添加重绘通知:

internal class MainViewModel : BaseViewModel
{
    double hayt;
    public double Hayt
    {
        get => hayt;
        set
        {
            if (hayt != value)
            {
                hayt = value;
                OnPropertyChanged();
                // 发送重绘通知
                MessagingCenter.Send(this, "InvalidateChart");
            }
        }
    }
}

3. 调整XAML布局

移除冗余资源定义,正确绑定CustomChart作为GraphicsView的Drawable:

<ContentPage.BindingContext>
    <viewmodel:MainViewModel />
</ContentPage.BindingContext>

<ScrollView>
    <VerticalStackLayout>
        <HorizontalStackLayout
            Spacing="25"
            Padding="30,0"
            VerticalOptions="Center">

            <Slider 
                Minimum="0.3"
                Maximum="1.0"
                Value="{Binding Hayt}"
                WidthRequest="200" />

        </HorizontalStackLayout>

        <GraphicsView x:Name="ChartView" HeightRequest="300">
            <GraphicsView.Drawable>
                <charts:CustomChart Grid_Height="{Binding Hayt}" />
            </GraphicsView.Drawable>
        </GraphicsView>

    </VerticalStackLayout>
</ScrollView>

4. 添加重绘触发逻辑

在MainPage后台代码订阅重绘通知,触发GraphicsView重绘:

public MainPage()
{
    InitializeComponent();
    MessagingCenter.Subscribe<MainViewModel>(this, "InvalidateChart", _ => ChartView.Invalidate());
}

protected override void OnDisappearing()
{
    base.OnDisappearing();
    MessagingCenter.Unsubscribe<MainViewModel>(this, "InvalidateChart");
}

关键说明

  • BindableObject继承:自定义Drawable类必须继承BindableObject才能拥有可绑定属性,实现数据绑定。
  • 重绘触发:属性值变化时需主动调用GraphicsView.Invalidate(),否则画布不会自动更新。除MessagingCenter外,也可使用.NET MAUI WeakReferenceMessenger或绑定Command实现更优雅的重绘触发。

内容的提问来源于stack exchange,提问作者Passisimple

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:35:35