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

Xamarin.Forms绑定异常:点击按钮跳转后新页面无内容显示

Xamarin.Forms 页面无法显示嵌入资源图片与文本的问题修复

核心问题分析与修复步骤

1. 绑定上下文与数据类型不匹配

XAML中设置了x:DataType="models:Mem",但页面的BindingContext是MemViewModel,直接绑定imageSource、interpretation会找不到对应属性——这些属性实际在MemViewModel的Mem对象里。

错误绑定代码:

<Image Source="{Binding imageSource}" .../>
<Label Text="{Binding interpretation}" .../>

修复后XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:models="clr-namespace:MDivination.Models" 
             xmlns:viewmodels="clr-namespace:MDivination.ViewModels"
             x:DataType="viewmodels:MemViewModel" <!-- 修正数据类型为ViewModel -->
             x:Class="MDivination.Views.DivinationResult">

    <ContentPage.Content>
        <StackLayout>
            <!-- 绑定路径改为ViewModel中的Mem对象属性 -->
            <Image Source="{Binding Mem.imageSource}" Aspect="AspectFit"  
                   VerticalOptions="Center"
                   HorizontalOptions="Center"
                   HeightRequest="100" WidthRequest="100"/>
            <Label Text="{Binding Mem.interpretation}"
                   VerticalOptions="Center"
                   HorizontalOptions="Center"
                   TextColor="Purple"/>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

同时删除XAML中重复设置的<ContentPage.BindingContext>节点,保留页面构造函数的BindingContext赋值即可,避免冲突。

2. Mem类属性的无限递归与初始化错误

Mem类的属性存在无限递归(get返回自身),且资源加载逻辑写在setter里但从未被触发,导致属性值始终为null。

错误的Mem类属性:

public int id
{
    get { return id; } // 无限递归,直接返回自身
    set
    {
        Random random = new Random();
        id = random.Next(0,2);
        OnPropertyChanged(nameof(id));
    }
}

public ImageSource imageSource
{
    get { return imageSource; } // 同样递归
    set {
        var assembly = IntrospectionExtensions.GetTypeInfo(typeof(MemViewModel)).Assembly;
        imageSource = ImageSource.FromResource($"MDivination.Images.{id}.png"); 
        OnPropertyChanged(nameof(imageSource)); }
}

修复后的Mem类:

namespace MDivination.Models
{
    public class Mem : INotifyPropertyChanged
    {
        // 用私有字段存储值,避免递归
        private int _id;
        private ImageSource _imageSource;
        private string _interpretation;
        private string _history;

        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }

        public Mem() 
        {
            // 构造函数中直接初始化随机ID并加载资源
            Random random = new Random();
            _id = random.Next(0, 2);
            LoadImage();
            LoadInterpretation();
        }

        public int id
        {
            get { return _id; }
            set
            {
                _id = value;
                OnPropertyChanged(nameof(id));
                // ID变化时重新加载资源
                LoadImage();
                LoadInterpretation();
            }
        }

        public ImageSource imageSource
        {
            get { return _imageSource; }
            private set 
            {
                _imageSource = value;
                OnPropertyChanged(nameof(imageSource)); 
            }
        }

        public string interpretation
        {
            get { return _interpretation; }
            private set
            {
                _interpretation = value;
                OnPropertyChanged(nameof(interpretation));
            }
        }

        public string history
        {
            get { return _history; }
            private set
            {
                _history = value;
                OnPropertyChanged(nameof(history));
            }
        }

        // 封装资源加载逻辑,避免重复代码
        private void LoadImage()
        {
            var assembly = IntrospectionExtensions.GetTypeInfo(typeof(Mem)).Assembly;
            imageSource = ImageSource.FromResource($"MDivination.Images.{_id}.png");
        }

        private void LoadInterpretation()
        {
            var assembly = IntrospectionExtensions.GetTypeInfo(typeof(Mem)).Assembly;
            // 加空判断,避免资源不存在时崩溃
            using (Stream stream = assembly.GetManifestResourceStream($"MDivination.Interpretation.{_id}.txt"))
            {
                interpretation = stream != null ? new StreamReader(stream).ReadToEnd() : "资源未找到";
            }
        }
    }
}

3. 嵌入资源的生成操作验证

确保图片和文本文件的生成操作设置为Embedded Resource,且资源命名空间与代码中的路径一致:

  • 图片路径示例:MDivination.Images.0.png、MDivination.Images.1.png
  • 文本路径示例:MDivination.Interpretation.0.txt、MDivination.Interpretation.1.txt

可以通过以下代码输出所有嵌入资源名称,检查路径是否正确:

// 在LoadImage方法中添加调试代码
var assembly = IntrospectionExtensions.GetTypeInfo(typeof(Mem)).Assembly;
var resourceNames = assembly.GetManifestResourceNames();
foreach (var name in resourceNames)
{
    System.Diagnostics.Debug.WriteLine(name);
}

4. ViewModel的Navigation属性初始化

确保MemViewModel的Navigation属性在跳转前被赋值,比如在主页面构造函数中:

// 主页面代码示例
public MainPage()
{
    InitializeComponent();
    var vm = new MemViewModel();
    vm.Navigation = Navigation;
    BindingContext = vm;
}

内容的提问来源于stack exchange,提问作者Евгений Дельфонцев

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:10:58