Как добавить в ObservableCollection с помощью MVVM C# - PullRequest
1 голос
/ 29 мая 2020

Я делаю приложение xamrin.forms со страницами с вкладками, содержащими некоторые списки. Поэтому я решил попробовать подход MVVM, но никогда не делал этого раньше. Я пытался учиться на различных онлайн-уроках, и я понял концепцию, но мне явно не хватает чего-то.

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

Модель содержит класс ConnectedProjectors:

public class ConnectedProjectors
{
    public string ipaddress { get; set; }
    public string version { get; set; }
    public string swversion { get; set; }

    public Color activeStatus { get; set; }


    public override string ToString()
    {
        return ipaddress;
    }

}

В ViewModel у меня есть 2 класса ProjectorViewModel, которые наследуются от ViewModelBase:

 public class ProjectorViewModel : ViewModelBase
{
    private ProjectorServices service;


    public ProjectorViewModel()
    {
        service = new ProjectorServices();
        ProjectorList = new ObservableCollection<ConnectedProjectors>();
        ProjectorList = service.GetProjectors("test", "test", "test", Color.White); //Works as expected
    }

    public void AddProjector(string ip, string ver, string sw, Color color)
    {
        ProjectorList = service.GetProjectors(ip, ver, sw, color); //I expected this to add to the list
    }


    private ObservableCollection<ConnectedProjectors> connectedProjectors;
    public ObservableCollection<ConnectedProjectors> ProjectorList
    {
        get { return connectedProjectors; }
        set { SetProperty(ref connectedProjectors, value); } // Maybe the NotifyEvent doesn't work as expected?
    }

}

public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected bool SetProperty<T>(ref T storage, T value,
        [CallerMemberName] string propertyName = null)
    {
        if (Object.Equals(storage, value))
            return false;

        storage = value;
        OnPropertyChanged(propertyName);
        return true;
    }

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

плюс класс ProjectorServices:

 class ProjectorServices
{
    public ProjectorServices()
    {

    }

    public ObservableCollection<ConnectedProjectors> GetProjectors(string ipad, string ver, string sw, Color color)
    {
        var list = new ObservableCollection<ConnectedProjectors>
        {
            new ConnectedProjectors
            {
                ipaddress = ipad,
                version = ver,
                swversion = sw,
                activeStatus = color                   
            }
        };

        return list;
    }
}

и, наконец, класс MainPage:

   public partial class MainPage : ContentPage
{
    public ConnectedProjectors projectors;
    private ProjectorViewModel projvm = new ProjectorViewModel();
    public MainPage()
    {
        InitializeComponent();

        this.BindingContext = new ProjectorViewModel();
    }
     public void AddProj(object sender,EventArgs e)
    {
        string ip = txt.Text;  // text input in editor in MainView view.
        string pn = "Not Found";
        string sw = "Not Found";
        Color col = Color.Chocolate;

        try
        {
            pn = GetPartNr(ip); // Sends an ascii command to see if the ipaddress returns an expected result
            sw = GetSWVersion(ip);
            col = GetActiveStatus(ip);
        }

        finally
        {
            projvm.AddProjector(ip, pn, sw, col);
        }
    }
}

Результатом кода в его нынешнем виде является то, что команда in ProjectorViewModel () добавляет в коллекцию Observable по мере инициализации приложения, как ожидалось. Но в методе AddProjector (), который я написал чуть ниже, та же команда не добавляет новый элемент в коллекцию (по крайней мере, не отображается в списке).

в XAML У меня есть элемент Listview ItemSource, связанный с ProjectorList, и в списке отображается тестовый элемент, но когда я нажимаю кнопку, которая запускает метод AddProj (), ничего не происходит.

Я ожидаю, что проблема связана с одним из двух:

1) Я пытаюсь добавить в коллекцию неправильно.

2) PropertyChanged не работает должным образом

Я надеялся, что кто-то может мне с этим помочь. Любая помощь будет очень признательна.

1 Ответ

1 голос
/ 29 мая 2020

Вы правы в том, в чем проблема. Ваш MainPage имеет BindingContext, установленный на новый экземпляр ProjectorViewModel.

this.BindingContext = new ProjectorViewModel();

Однако метод AddProj добавляет новую ViewModel к projvm, который является просто частным полем, сидит там. Он не имеет никакого отношения к странице и ее привязке. Лучший подход - предоставить ViewModel вашего BindingContext в свойстве и использовать его.

public ProjectorViewModel ViewModel
{
    get => this.BindingContext as ProjectorViewModel;
    set => this.BindingContext = value;
}

А затем вы можете установить свой BindingContext следующим образом:

public HomePage()
{
    InitializeComponent();

    this.ViewModel = new ProjectorViewModel();
}

Таким образом мы настроили снова наш контекст, но на этот раз у нас есть к нему доступ. Теперь вы можете добавить свою новую ViewModel следующим образом:

this.ViewModel.AddProjector(ip, pn, sw, col);

Теперь вы будете использовать тот же экземпляр, к которому привязана ваша страница.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...