Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
240 views
in Technique[技术] by (71.8m points)

c# - SyncFusion Xamarin Forms DataForm throws NullReferenceException after setting DataObject

I have the following code in my Xamarin Forms project (it is from the official sample project of Syncfusion).

ViewModel:

  [Preserve(AllMembers = true)]
  public class RecipientInfoViewModel : INotifyPropertyChanged
  {
    
    private RecipientInfo recipientInfo;
       
    private bool isVisible;
       
    public RecipientInfoViewModel()
    {
      this.recipientInfo = new RecipientInfo();
      this.isVisible = true;
      this.CommitCommand = new Command<object>(this.OnCommit);
    }

   
    public event PropertyChangedEventHandler PropertyChanged;

    
    public RecipientInfo RecipientInfo
    {
      get { return this.recipientInfo; }
      set { this.recipientInfo = value; }
    }

   
    public bool IsVisible
    {
      get
      {
        return this.isVisible;
      }

      set
      {
        this.isVisible = value;
        this.OnPropertyChanged("IsVisible");
      }
    }

    
    public Command<object> CommitCommand { get; set; }

    /// <summary>
    /// Commits the value of the specific editor to corresponding property in the business object.
    /// </summary>
    /// <param name="dataForm">The corresponding DataForm.</param>
    private void OnCommit(object dataForm)
    {
      var dataFormLayout = dataForm as Syncfusion.XForms.DataForm.SfDataForm;
      var isValid = dataFormLayout.Validate();
      dataFormLayout.Commit();
      if (!isValid)
      {
        App.Current.MainPage.DisplayAlert("Alert", "Please enter valid details", "Ok");
        return;
      }

      App.Current.MainPage.DisplayAlert("Alert", "Money Transferred", "Ok");
      dataFormLayout.IsReadOnly = true;
      this.IsVisible = false;
    }
        
    private void OnPropertyChanged(string propertyName)
    {
      if (this.PropertyChanged != null)
      {
        this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    }
  }

Page:

<?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:sync="clr-namespace:Syncfusion.XForms.DataForm;assembly=Syncfusion.SfDataForm.XForms"
             xmlns:local2="clr-namespace:TestProject.Helpers"
             xmlns:local="clr-namespace:TestProject.ViewModels"
             x:Class="TestProject.Views.GettingStarted">
  <ContentPage.BindingContext>
    <local:RecipientInfoViewModel />
  </ContentPage.BindingContext>
  <ContentPage.Content>
    <Grid Margin="0">
      <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="60" />
      </Grid.RowDefinitions>
      <sync:SfDataForm x:Name="dataForm" LayoutOptions="TextInputLayout" ValidationMode="Explicit" DataObject="{Binding RecipientInfo}">
        <sync:SfDataForm.Behaviors>
          <local2:SfDataFormGettingStartedBehavior />
        </sync:SfDataForm.Behaviors>
      </sync:SfDataForm>
      <Button x:Name="transferMoney" Grid.Row="1"  Text="Transfer Money" TextColor="#FFFFFF"
                  WidthRequest="150" HeightRequest="40" BackgroundColor="#2196F3" HorizontalOptions="Center"
                    VerticalOptions="Center"
                  Command="{Binding Path=BindingContext.CommitCommand, Source={x:Reference Name=dataForm}}"
                                                CommandParameter="{Binding Source={x:Reference Name=dataForm}}"
                     IsVisible="{Binding IsVisible, Mode=TwoWay}" />
    </Grid>
  </ContentPage.Content>
</ContentPage>

Model:

 /// <summary>
  /// Describes the possible account type.
  /// </summary>
  [Preserve(AllMembers = true)]
  public enum AccountType
  {
    /// <summary>
    /// Represents savings account type.
    /// </summary>
    Savings,

    /// <summary>
    /// Represents current account type.
    /// </summary>
    Current,

    /// <summary>
    /// Represents overdraft account type.
    /// </summary>
    Overdraft,

    /// <summary>
    /// Represents cashcredit account type.
    /// </summary>
    CashCredit,

    /// <summary>
    /// Represents loan account type.
    /// </summary>
    LoanAccount,

    /// <summary>
    /// Represents NRE account type.
    /// </summary>
    NRE,

    /// <summary>
    /// Represents cardpayment type.
    /// </summary>
    CardPayment
  }

  /// <summary>
  /// Represents the recipient information of the data form getting started sample.
  /// </summary>
  [Preserve(AllMembers = true)]
  public class RecipientInfo : INotifyPropertyChanged, INotifyDataErrorInfo
  {
    #region Fields

    /// <summary>
    /// Represents the account number of the recipient information.
    /// </summary>
    private string accountNumber;

    /// <summary>
    /// Represents the second account number of the recipient information.
    /// </summary>
    private string accountNumber1;

    /// <summary>
    /// Represents the email id of the recipient information.
    /// </summary>
    private string email;

    /// <summary>
    /// Represents the amount of the recipient information.
    /// </summary>
    private double? amount = null;

    /// <summary>
    /// Represents the name of the recipient information.
    /// </summary>
    private string name;

    /// <summary>
    /// Represents the swift of the recipient information.
    /// </summary>
    private string swift;

    /// <summary>
    /// Represents the terms and conditions of the recipient information.
    /// </summary>
    private bool agree;

    /// <summary>
    /// Represents the password of the recipient information.
    /// </summary>
    private string password;

    /// <summary>
    /// Represents the account type of the recipient information.
    /// </summary>
    private AccountType accountType;

    /// <summary>
    /// Represents the immutable email regular expression.
    /// </summary>
    private Regex emailRegex = new Regex(@"^([w.-]+)@([w-]+)((.(w){2,3})+)$");

    /// <summary>
    /// Represents a collection of keys and values.
    /// </summary>
    private Dictionary<string, List<string>> propErrors = new Dictionary<string, List<string>>();

    /// <summary>
    /// Represents a immutable regular expression.
    /// </summary>
    private Regex swiftRegex = new Regex("^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$");

    #endregion Fields

    #region Constructor

    /// <summary>
    /// Initializes a new instance of the <see cref="RecipientInfo"/> class.
    /// </summary>
    public RecipientInfo()
    {
    }

    /// <summary>
    /// Represents the method that will handle when a property is changed on a component.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Represents the method that will handle when a Errors are changed.
    /// </summary>
    public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;

    #endregion Constructor

    #region Public Properties

    /// <summary>
    /// Gets a value indicating whether recipient information contains errors.
    /// </summary>
    ////[Display(AutoGenerateField = false)]
    public bool HasErrors
    {
      get
      {
        var propErrorsCount = this.propErrors.Values.FirstOrDefault(r => r.Count > 0);
        if (propErrorsCount != null)
        {
          return true;
        }
        else
        {
          return false;
        }
      }
    }

    /// <summary>
    /// Gets or sets the account number field.
    /// </summary>
    [Display(ShortName = "Account number")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter account number.")]
    public string AccountNumber
    {
      get
      {
        return this.accountNumber;
      }

      set
      {
        if (value != this.AccountNumber)
        {
          this.accountNumber = value;
          this.RaisePropertyChanged("AccountNumber");
          this.RaiseErrorChanged("AccountNumber");
        }
      }
    }

    /// <summary>
    /// Gets or sets the first account number field.
    /// </summary>
    [Display(ShortName = "Re-enter account number")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please re-enter account number.")]
    public string AccountNumber1
    {
      get
      {
        return this.accountNumber1;
      }

      set
      {
        if (value != this.AccountNumber1)
        {
          this.accountNumber1 = value;
          this.RaisePropertyChanged("AccountNumber1");
          this.RaiseErrorChanged("AccountNumber1");
        }
      }
    }

    /// <summary>
    /// Gets or sets the SWIFT field.
    /// </summary>
    [Display(Order = 0, ShortName = "SWIFT code", Prompt = "Enter 8 or 11 upper case letters")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter the SWIFT code.")]
    [DisplayOptions(ValidMessage = "Name length is enough")]
    public string SWIFT
    {
      get
      {
        return this.swift;
      }

      set
      {
        this.swift = value;
        this.RaisePropertyChanged("SWIFT");
        this.RaiseErrorChanged("SWIFT");
      }
    }

    /// <summary>
    /// Gets or sets the name field.
    /// </summary>
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter the name.")]
    public string Name
    {
      get
      {
        return this.name;
      }

      set
      {
        this.name = value;
        this.RaisePropertyChanged("Name");
        this.RaiseErrorChanged("Name");
      }
    }

    /// <summary>
    /// Gets or sets the email field.
    /// </summary>
    [Display(ShortName = "Email")]
    [EmailAddress(ErrorMessage = "Please enter a valid e-mail id.")]
    public string Email
    {
      get
      {
        return this.email;
      }

      set
      {
        this.email = value;
        this.RaisePropertyChanged("Email");
        this.RaiseErrorChanged("Email");
      }
    }

    /// <summary>
    /// Gets or sets the ammount field.
    /// </summary>
    [Display(ShortName = "Amount")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Please enter the amount.")]
    public double? Amount
    {
      get
      {
        return this.amount;
      }

      set
      {
        this.amount = value;
        this.RaisePropertyChanged("Amount");
        this.RaiseErrorChanged("Amount");
      }
    }

    /// <summary>
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...