Xamarin 表单未实现绑定

Posted

技术标签:

【中文标题】Xamarin 表单未实现绑定【英文标题】:Xamarin forms is not implementing Binding 【发布时间】:2021-09-28 23:16:56 【问题描述】:

我是 Xamarin 表单的新手,我正在尝试使用一些输入创建一个简单的应用程序并将它们保存在数据库中。但是绑定似乎不起作用,我不确定出了什么问题。

这是模型:

using SQLite;
using System;
using System.Collections.Generic;
using System.Text;

namespace SiteVisits.Models

    [Table("Well")]
    public class Well
    
        [PrimaryKey, AutoIncrement]
        public int ID  get; set; 
        public string LatitudeCoordinates  get; set; 
        public string LongitudeCoordinates  get; set; 
    

视图模型:

using MvvmHelpers;
using MvvmHelpers.Commands;
using SiteVisits.Data;
using SiteVisits.Models;
using SiteVisits.Services;
using SiteVisits.Views;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace SiteVisits.ViewModels

    public class WellViewModel : BaseViewModel
    
        public AsyncCommand SaveCommand  get; private set; 
        public int ID  get; set; 

        public WellViewModel()
        
            Title = "Well Information";           
            SaveCommand = new AsyncCommand(Save);
            var wellService = DependencyService.Get<IWellDataStore>();
        
     
        string latitudeCoordinates, longitudeCoordinates;
        public string LatitudeCoordinates
        
            get => latitudeCoordinates;
            set
            
                latitudeCoordinates = value;
                OnPropertyChanged("LatitudeCoordinates");
            
        
        public string LongitudeCoordinates
        
            get => longitudeCoordinates;
            set
            
                longitudeCoordinates = value;
                OnPropertyChanged("LongitudeCoordinates");
            
        

        private async Task Save()
        
            if (string.IsNullOrWhiteSpace(latitudeCoordinates) ||
               string.IsNullOrWhiteSpace(longitudeCoordinates))
            
                return;
            

            await WellDataStore.AddWell(latitudeCoordinates, longitudeCoordinates);

            // This will pop the current page off the navigation stack
            await Shell.Current.GoToAsync("..");
        
    

服务:

using SiteVisits.Models;
using SQLite;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Essentials;

namespace SiteVisits.Services

    public class WellDataStore
    
        static SQLiteAsyncConnection db;
        static async Task Init()
        
            if (db != null)
                return;
            // Get an absolute path to the database file
            var databasePath = Path.Combine(FileSystem.AppDataDirectory, "MyData.db");

            db = new SQLiteAsyncConnection(databasePath);
            await db.CreateTableAsync<Well>();

        
        public static async Task AddWell(string latitudeCoordinates, string longitudeCoordinates)
        
            await Init();
            var well = new Well()
            
                LatitudeCoordinates = latitudeCoordinates,
                LongitudeCoordinates = longitudeCoordinates
            ;
            await db.InsertAsync(well);
        
        public async Task<Well> GetWell(int id)
        
            await Init();

            var well = await db.Table<Well>()
                .FirstOrDefaultAsync(c => c.ID == id);

            return well;
        

    

界面:

using SiteVisits.Models;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace SiteVisits.Services

    public interface IWellDataStore
    
        Task AddWell(string latitudeCoordinates, string longitudeCoordinates);
        Task<Well> GetWell(int id);
    

查看:

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:viewModel="clr-namespace:SiteVisits.ViewModels" x:DataType="viewModel:WellViewModel"
             x:Class="SiteVisits.Views.WellInfo">
    <ContentPage.BindingContext>
        <viewModel:WellViewModel />
    </ContentPage.BindingContext>
    <ContentPage.ToolbarItems>
        <ToolbarItem Text="Save" Command="Binding SaveCommand"></ToolbarItem>
    </ContentPage.ToolbarItems>
    <AbsoluteLayout>
        <StackLayout AbsoluteLayout.LayoutBounds = "0,0,1,1" AbsoluteLayout.LayoutFlags = "All">
            <ScrollView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                
                <StackLayout Spacing="20" Padding="15" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">

                    <Label Text="Latitude Coordinates:" />
                    <Entry BindingContext="Binding LatitudeCoordinates" x:Name="LatitudeCoordinates" FontSize="Medium"/>

                    <Label Text="Longitude Coordinates:" />
                    <Entry BindingContext="Binding LongitudeCoordinates" x:Name="LongitudeCoordinates" FontSize="Medium"/>
                </StackLayout>
            </ScrollView>
        </StackLayout>
    </AbsoluteLayout>
</ContentPage>

还有 xaml.cs:

using SiteVisits.Models;
using SiteVisits.Services;
using SiteVisits.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Xamarin.Forms;
using Xamarin.Forms.Xaml;

namespace SiteVisits.Views

    [XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class WellInfo : ContentPage
    
        WellViewModel viewModel;
      
        public WellInfo(WellViewModel viewModel)
        
            InitializeComponent();

            this.viewModel = viewModel;
            BindingContext = this.viewModel;
        

        public WellInfo()
        
            InitializeComponent();

            viewModel = new WellViewModel();
            BindingContext = viewModel;
        

    

BaseViewModel 的类型为 INotifyPropertyChanged。当我在 Task Save() 中的 ViewModel 中放置断点时,它显示 latitudeCoordinates 和 longitudeCoordinate 为空,即使我已尝试将值放入其中。

非常感谢任何帮助!

【问题讨论】:

您在构造函数和 XAML 中设置了 BindingContext 两次。从 XAML 中删除它 我删除了这个位` `,它仍然无法工作。 当您更新 UI 时,绑定属性的设置器会被调用吗? 不,只有 get 被调用,但 set 永远不会通过断点。 这很奇怪。如果您想将项目发布到某个地方,我会快速浏览一下。 【参考方案1】:

这是错误的

<Entry BindingContext="Binding LatitudeCoordinates" FontSize="Medium"/>

你需要绑定Text属性

<Entry Text="Binding LatitudeCoordinates" FontSize="Medium"/>

【讨论】:

效果很好!谢谢!现在我可以看到设置器中的值。但是现在当它到达 vm 中的await WellDataStore.AddWell(LatitudeCoordinates, LongitudeCoordinates); 时,我得到一个错误 System.NullReferenceException: 'Object reference not set to an instance of an object.' 并且在线程中它说 System. Diagnostics.Debugger.Mono_UnhandledException_internal()。知道这可能是什么吗? 你的虚拟机永远不会初始化WellDataStore Right.. 所以我在 vm IWellDataStore wellService; & WellViewModel 类中添加了 `wellService = DependencyService.Get();` 并将 AddWell 的位更改为 await wellService.AddWell(latitudeCoordinates, longitudeCoordinates); 并给出我同样的错误。 something is null,你需要弄清楚它是什么。最可能的罪魁祸首是wellService - 在调用DependencyService 之后,您是否检查过它是否为空? 是的,你是对的,wellService 返回为空。它虽然被初始化为public interface,那么它为空的原因是什么?

以上是关于Xamarin 表单未实现绑定的主要内容,如果未能解决你的问题,请参考以下文章

子列表未绑定到 xamarin 表单中的 ListView 分组

Xamarin Forms Switch Toggled 事件未与视图模型绑定

Xamarin 表单:显示和绑定具有多行和多列的列表/网格的数据

具有绑定问题的 Xamarin 表单 FlyoutPage

在 xamarin 表单上动态绑定图像源

Xamarin 表单从 listview 绑定到 viewmodel