【问题标题】:Xamarin forms is not implementing BindingXamarin 表单未实现绑定
【发布时间】: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 永远不会通过断点。
  • 这很奇怪。如果您想将项目发布到某个地方,我会快速浏览一下。

标签: c# sqlite xamarin xamarin.forms binding


【解决方案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,那么它为空的原因是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-10
  • 2018-12-16
  • 2020-07-03
  • 2017-10-11
  • 2015-03-11
  • 1970-01-01
相关资源
最近更新 更多