Приложение аварийного завершения строительства ViewModel - PullRequest
0 голосов
/ 24 декабря 2018

Я пытаюсь выучить формы Xamarin, установив контакт с Заметками (один ко многим).Я сделал ListView с привязкой ContactsViewModel, работающей хорошо.

Так что теперь я пытаюсь сделать кнопку редактирования контекста:

public void OnEdit(object sender, EventArgs e)
{
    Contact contact = ((MenuItem)sender).CommandParameter as Contact;
    Navigation.PushAsync(new ContactPage(contact));
}

Итак, здесь я отправляю свой контакт на страницус базовой записью конструктор этой ContactPage:

public ContactPage(Contact contact)
{
    InitializeComponent();
    BindingContext = new ContactViewModel()
    {
        Id = contact.Id,
        Firstname = contact.Firstname,
        Lastname = contact.Lastname,
        Email = contact.Email,
        Address = contact.Address,
        Notes = contact.Notes
    };
}

Но когда я нажимаю на кнопку редактирования контекста, я получаю сбой приложения, я не понимаю, почему.

Вотхранилище, если вам нужно глубже изучить код: https://github.com/yerffeog/Contactium

Спасибо за ваше внимание, я также открыт для любой критики кода и улучшений.

При удалении аргументов это работаетно когда я привожу только один аргумент, я получаю крах.

1 Ответ

0 голосов
/ 24 декабря 2018

Убедитесь, что на страницу передается правильное значение.

public async void OnEdit(object sender, EventArgs e) { 
    Contact contact = ((MenuItem)sender).CommandParameter as Contact;
    if(contact != null) {
        var contactPage = new ContactPage(contact);
        await Navigation.PushAsync(contactPage);
    }
}

На основе предоставленного кода хранилища,

Эта модель просмотра

public class ContactViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ContactViewModel()
    {

    }

    /// <summary>
    /// Event when property changed.
    /// </summary>
    /// <param name="s">string</param>
    void OnPropertyChanged(string s)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(s));
    }

    /// <summary>
    /// Id of the contact.
    /// </summary>
    public int Id {
        get
        {
            return Id;
        }

        set
        {
            Id = value;
            OnPropertyChanged(nameof(Id));
        }
    }

    /// <summary>
    /// Lastname of the contact.
    /// </summary>
    public string Lastname {
        get
        {
            return Lastname;
        }

        set
        {
            Lastname = value;
            OnPropertyChanged(nameof(Lastname));
        }
    }

    /// <summary>
    /// Firstname of the contact.
    /// </summary>
    public string Firstname {
        get
        {
            return Firstname;
        }

        set
        {
            Firstname = value;
            OnPropertyChanged(nameof(Firstname));
        }
    }

    /// <summary>
    /// Email of the contact.
    /// </summary>
    public string Email {
        get
        {
            return Email;
        }

        set
        {
            Email = value;
            OnPropertyChanged(nameof(Email));
        }
    }

    /// <summary>
    /// Address of the contact.
    /// </summary>
    public string Address
    {
        get
        {
            return Address;
        }

        set
        {
            Address = value;
            OnPropertyChanged(nameof(Address));
        }
    }

    /// <summary>
    /// Notes of the contact.
    /// </summary>
    public List<Note> Notes
    {
        get
        {
            return Notes;
        }

        set
        {
            Notes = value;
            OnPropertyChanged(nameof(Notes));
        }
    }
}

Вышеприведенный код потерпит неудачу, так как свойства ссылаются на себя, что приведет к переполнению стека и аварийному завершению приложения.

Чтобы избежать повторения кода, создайте базовую модель представления с основами

public class ViewModelBase : INotifyPropertyChanged {
    public event PropertyChangedEventHandler PropertyChanged;
    /// <summary>
    /// Event when property changed.
    /// </summary>
    /// <param name="s">string</param>
    protected void OnPropertyChanged([CallerMemberName] string member = "") {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(member));
    }
}

Оттуда убедитесь, что модель представления имеет вспомогательные поля для открытых свойств.

public class ContactViewModel : ViewModelBase {
    private string id;
    /// <summary>
    /// Id of the contact.
    /// </summary>
    public int Id {
        get { return id; }
        set {
            id = value;
            OnPropertyChanged();
        }
    }

    string lastname;
    /// <summary>
    /// Lastname of the contact.
    /// </summary>
    public string Lastname {
        get { return lastname; }
        set {
            lastname = value;
            OnPropertyChanged();
        }
    }

    string firstname
    /// <summary>
    /// Firstname of the contact.
    /// </summary>
    public string Firstname {
        get { return firstname; }
        set {
            firstname = value;
            OnPropertyChanged();
        }
    }

    string email;
    /// <summary>
    /// Email of the contact.
    /// </summary>
    public string Email {
        get { return email; }
        set {
            email = value;
            OnPropertyChanged();
        }
    }

    string address;
    /// <summary>
    /// Address of the contact.
    /// </summary>
    public string Address {
        get { return address; }
        set {
            address = value;
            OnPropertyChanged();
        }
    }

    string notes;
    /// <summary>
    /// Notes of the contact.
    /// </summary>
    public List<Note> Notes {
        get { return notes; }
        set {
            notes = value;
            OnPropertyChanged();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...