[英]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:我希望这个问题是以下两件事之一:
The way I try to add to collection is not correct我尝试添加到收藏的方式不正确
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.