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

.NET MAUI中PlayMCanvas绑定值为Null问题求助

.NET MAUI绑定失败问题解决

问题根源

  1. PlayMCanvas继承结构错误:你让PlayMCanvas同时继承GraphicsView并实现IDrawable,但在XAML中已经使用GraphicsView并将其Drawable设置为PlayMCanvas,这种双重继承会导致绑定上下文混乱,无法正确传递ViewModel的属性值。
  2. ViewModel未实现属性变更通知:虽然当前是初始化赋值,但未实现INotifyPropertyChanged会导致后续属性更新无法同步到UI,不符合MVVM的核心要求。
  3. BindableProperty定义不够严谨:未设置默认值,当绑定失败时会直接为null。

修改后的代码

1. 修正PlayMCanvas(仅实现IDrawable)

using Microsoft.Maui.Graphics;
using Microsoft.Maui.Controls;

namespace PlayMApp.Drawables
{
    public class PlayMCanvas : BindableObject, IDrawable
    {
        public string Play
        {
            get => (string)GetValue(PlayProperty);
            set => SetValue(PlayProperty, value);
        }

        public static readonly BindableProperty PlayProperty =
            BindableProperty.Create(nameof(Play), typeof(string), typeof(PlayMCanvas), string.Empty);

        public void Draw(ICanvas canvas, RectF dirtyRect)
        {
            canvas.StrokeColor = Colors.Red;
            canvas.StrokeSize = 6;
            canvas.DrawLine(10, 10, 90, 100);
            // 增加空值判断,避免绘制异常
            canvas.DrawString(Play ?? "未获取到数据", 40, 30, HorizontalAlignment.Left);
        }
    }
}

注意:需要继承BindableObject才能使用BindableProperty,之前继承GraphicsView是冗余且错误的。

2. ViewModel实现INotifyPropertyChanged

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace PlayMApp
{
    public class ShowViewModel : INotifyPropertyChanged
    {
        private string _theString;
        public string TheString
        {
            get => _theString;
            set
            {
                if (_theString != value)
                {
                    _theString = value;
                    OnPropertyChanged();
                }
            }
        }

        public ShowViewModel()
        {
            TheString = "test";
        }

        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

3. 修正XAML的ContentPage闭合标签

原XAML中Title="Show Play"后缺少闭合的>,修正后:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:drawables="clr-namespace:PlayMApp.Drawables"
             xmlns:local="clr-namespace:PlayMApp"
             x:Class="PlayMApp.ShowPlay"
             x:DataType="local:ShowViewModel"        
             Title="Show Play">

    <VerticalStackLayout>
        <Label 
            Text="Welcome to .NET MAUI!"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
        
        <Button 
            Text="Add Motion"
            Clicked="AddMotion" 
            VerticalOptions="Start"
            HorizontalOptions="Center"></Button>
        
        <GraphicsView HeightRequest="300" WidthRequest="400">
            <GraphicsView.Drawable>
                <drawables:PlayMCanvas Play="{Binding TheString}" />
            </GraphicsView.Drawable>
        </GraphicsView>
    </VerticalStackLayout>
</ContentPage>

验证结果

修改后运行代码,PlayMCanvas的Play属性会正确获取到ViewModel中的test2值,Draw方法可以正常绘制该字符串。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 11:55:25