简体   繁体   English

如何使用 MVVM C# 添加到 ObservableCollection

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

I'm making a xamrin.forms application with tabbed pages containing some listviews.我正在制作一个带有包含一些列表视图的标签页的 xamrin.forms 应用程序。 So I decided to try the MVVM approach, but I've never done that before.所以我决定尝试 MVVM 方法,但我以前从未这样做过。 I have tried to learn from various online tutorials, and I get the concept, but there are some thing I'm missing apparently.我试图从各种在线教程中学习,并且我得到了这个概念,但是我显然缺少一些东西。

I want the user to be able to add to the list with the click of a button, but I just don't know how to do it.我希望用户能够通过单击按钮添加到列表中,但我只是不知道该怎么做。

The Model contains a class called ConnectedProjectors: 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;
    }

}

In ViewModel I have a 2 classes ProjectorViewModel which inherits from ViewModelBase:在 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));
    }
}

plus the ProjectorServices class:加上 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;
    }
}

and finally the MainPage class:最后是 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);
        }
    }
}

The result of the code as it is now, is that the command in ProjectorViewModel() method adds to the Observable collection as the application initializes as expected.现在的代码结果是,随着应用程序按预期初始化,ProjectorViewModel() 方法中的命令添加到 Observable 集合中。 But in the method AddProjector() that I wrote just below, the same command does not add a new item to the collection (At least not visible in listview).但是在我刚刚在下面编写的方法 AddProjector() 中,相同的命令不会将新项目添加到集合中(至少在列表视图中不可见)。

in XAML I have listview ItemSource bound to ProjectorList, and the listview shows the test item, but when I click the button that fires the AddProj()Method, nothing happens.在 XAML 中,我将 listview ItemSource 绑定到 ProjectorList,并且 listview 显示测试项目,但是当我单击触发 AddProj() 方法的按钮时,没有任何反应。

I expect that the issue is one of two things:我希望这个问题是以下两件事之一:

  1. The way I try to add to collection is not correct我尝试添加到收藏的方式不正确

  2. The PropertyChanged doesn't work as expected PropertyChanged 没有按预期工作

I was hoping someone could help me with this.我希望有人可以帮助我解决这个问题。 Any help would be very much appreciated.任何帮助将不胜感激。

You are correct in what the issue is.你的问题是正确的。 Your MainPage has its BindingContext set to a new instance of ProjectorViewModel .您的MainPage将其BindingContext设置为ProjectorViewModel的新实例。

this.BindingContext = new ProjectorViewModel();

However, AddProj method adds the new ViewModel to projvm , which is just a private field, sitting there.但是, AddProj方法将新的 ViewModel 添加到projvm ,这只是一个私有字段,坐在那里。 It has no connection whatsoever to the page and its binding.它与页面及其绑定没有任何关系。 A better approach is to expose your BindingContext's ViewModel in a property and use it.更好的方法是在属性中公开 BindingContext 的 ViewModel 并使用它。

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

And then you can set your BindingContext like this:然后你可以像这样设置你的 BindingContext :

public HomePage()
{
    InitializeComponent();

    this.ViewModel = new ProjectorViewModel();
}

This way we have set up again our context, but this time we have access to it.通过这种方式,我们再次设置了上下文,但这次我们可以访问它。 Now, you can add your new ViewModel like this:现在,您可以像这样添加新的 ViewModel:

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

Now you will be using the same instance, that your page has been bound to.现在您将使用与您的页面绑定的相同实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将observablecollection添加到另一个observablecollection C# - How add observablecollection to another observablecollection c# 如何从C#MVVM中绑定到ObservableCollection的列表中删除对象 - How to remove objects from a list bound to an ObservableCollection in C# MVVM 如何在 MVVM WPF C# 的 ComboBox 中显示来自 ObservaBleCollection 的值 - How to Display Values from ObservaBleCollection in ComboBox In MVVM WPF C# C#MVVM:使用RelayCommand编辑ObservableCollection的SelectedItem - C# MVVM: Edit a SelectedItem of an ObservableCollection with a RelayCommand c#mvvm嵌套ObservableCollection CollectionChanged NewStartingIndex&gt; 0 - c# mvvm nested ObservableCollection CollectionChanged NewStartingIndex >0 C# WPF ListView MVVM ObservableCollection 在 ObservableCollection 内部 - C# WPF ListView MVVM ObservableCollection inside of an ObservableCollection C#ObservableCollection添加错误 - C# ObservableCollection Add error C#MVVM如何将命令添加到TextBlock - C# MVVM How to add Command to TextBlock C#WPF MVVM-如何填充ObservableCollection,然后在列表视图中加载数据? - C# WPF MVVM - How to populate ObservableCollection then later load data in listview? C# ObservableCollection 不会出现在 MVVM 的 TreeView 中 - C# ObservableCollection dosen't appear in TreeView by MVVM
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM