簡體   English   中英

如何使用 MVVM C# 添加到 ObservableCollection

[英]How to add to ObservableCollection with MVVM C#

我正在制作一個帶有包含一些列表視圖的標簽頁的 xamrin.forms 應用程序。 所以我決定嘗試 MVVM 方法,但我以前從未這樣做過。 我試圖從各種在線教程中學習,並且我得到了這個概念,但是我顯然缺少一些東西。

我希望用戶能夠通過單擊按鈕添加到列表中,但我只是不知道該怎么做。

Model 包含一個名為 ConnectedProjectors 的 class:

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 個繼承自 ViewModelBase 的類 ProjectorViewModel:

 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:

 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 class:

   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);
        }
    }
}

現在的代碼結果是,隨着應用程序按預期初始化,ProjectorViewModel() 方法中的命令添加到 Observable 集合中。 但是在我剛剛在下面編寫的方法 AddProjector() 中,相同的命令不會將新項目添加到集合中(至少在列表視圖中不可見)。

在 XAML 中,我將 listview ItemSource 綁定到 ProjectorList,並且 listview 顯示測試項目,但是當我單擊觸發 AddProj() 方法的按鈕時,沒有任何反應。

我希望這個問題是以下兩件事之一:

  1. 我嘗試添加到收藏的方式不正確

  2. PropertyChanged 沒有按預期工作

我希望有人可以幫助我解決這個問題。 任何幫助將不勝感激。

你的問題是正確的。 您的MainPage將其BindingContext設置為ProjectorViewModel的新實例。

this.BindingContext = new ProjectorViewModel();

但是, AddProj方法將新的 ViewModel 添加到projvm ,這只是一個私有字段,坐在那里。 它與頁面及其綁定沒有任何關系。 更好的方法是在屬性中公開 BindingContext 的 ViewModel 並使用它。

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);

現在您將使用與您的頁面綁定的相同實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM