I Have a view model and i want to access all the properties value in another class which is not a viewmodel. So how to pass whole viewmodel as a parameter into another class method or is there some other way to do this thing?
i wantto achieve something like below
Public Class ViewModel
{
var res = XYZClass.ExecuteAsync(ViewModel);
}
Public Static Class XYZClass{
public Static Task ExecuteAsync(ViewModel request)
{
throw new NotImplementedException();
}
}
Put in a public static property reference to the instantiated view model on the app class. Then it can be accessed it from any other class.
I worked on a Silverlight project which did that very thing with the VM and other globally shared data.
Related
I am working through an MVC Tutorial without a database.
Service Class
namespace Domain.Services
{
public class ThingService
{
private List<Thing> _things;
private List<Thing> Things
{
get
{
if (this._things == null)
{
this._things = new List<Thing>();
this._things.Add(new Thing()
{
ID = 1,
Name = "The red thing",
Color = "Red",
Size = "Small",
Length = 55,
DateAvailable = DateTime.Parse("1/1/2018"),
IsActive = true
});
// Add more things
}
return this._things;
}
}
Controller
namespace WWW.Controllers
{
public class HomeController : Controller
{
private readonly ThingService _thingService;
public HomeController()
{
this._thingService = new ThingService();
}
public ActionResult AddThing()
{
//add code for a new thing
return View();
}
}
}
I need help adding a new instance of my model to a list (_things? Things?). I have tried the way the Service Class does it and get scope resolution errors.
Can I do this through the _thingService variable available to me in my Controller?
Do I need to add a Method to my Service Class?
Any thoughts would be appreciated!
Thanks in advance.
There are a number of problems with your code. First of all, you're doing too much in your getter (Things). Properties by their very nature should be light-weight data access members. If you need to do heavy lifting, that's when you consider using a method instead of a property.
With that out of the way, you have a problem: every time someone accesses your list, it's going to be rebuilt, because that's the logic inside your getter; you instantiate and build your list anew every time.
Thirdly, you need to provide access to your property outside your class. Currently your Things property is private, so change it to public or internal.
Here is one simple way to do it:
public List<Thing> Things { get; } = new List<Thing>();
It's a public property (accessible outside your class) that instantiates the list when the class is constructed and provides read-only access to the list, i.e. a new list instance cannot be assigned to it. Here's how you can use it from another class:
this._thingService.Things.Add(...);
Your property is private:
private List<Thing> Things
{
//...
}
So, by design, nothing from other classes can access it. If you make it public:
public List<Thing> Things
{
//...
}
Then you can access it on any object instance:
public ActionResult AddThing()
{
this._thingService.Things.Add(new Thing());
return View();
}
Covnersely, if you want it to be private, then you'll need to provide some other way to access it. For example, a public method. At that point it would be worth reconsidering much of your service's design though because then you'd have a method which just accesses a property and a property with lots of logic in its getter. This is a bit unbalanced. Ideally the property would just be accessing the member data (perhaps with minimal logic) and your member initialization logic would be in a constructor or method.
It's worth noting also, however, that any new instance of ThingService is going to have an entirely new list of Things (after you first access the property, that is). So you can add a Thing in your controller, but as soon as you direct to any other page or do anything else you're starting over from scratch again. For example, if your controller action adds a Thing and then redirects back to the list of Things, that list will again be empty.
I want use a static class that must contains global variables, so I can access to all application controls simply from a variable.
Actually I've this implementation:
public static class Globals
{
public static HeadToHead Head2Head
{
get { return Resources.Controls.HeadToHead; }
}
}
in the case above, I want return the instance of HeadToHead control, the control look like this:
public partial class HeadToHead : UserControl
{
public static int HomeId = 0;
}
my goal is to access to the static variables of this control, like: Globals.Head2Head.HomeId
but I get this error on this line: get { return Resources.Controls.HeadToHead; }
HeadToHead is a type which is not valid in the given context
You're returning what looks like a type from a property that seems to be declaring an instance of that type. If you truly want to return that type, there's syntax for that (I don't remember any more, I think in c# it's classname.type). If you want to return an instance, then you need to get that instance from somewhere.
As an aside, static instances of UI controls are a bad idea, and a code smell.
You have to instantiate an instance of the type and return that. As you want a single global instance you could use the static constructor.
public static class Globals {
static Globals(){
Head2Head = new Resources.Controls.HeadToHead();
}
public static HeadToHead Head2Head { get; private set; }
}
There are few situations in which you would actually want to do this but common static settings that do not change in the life of the application might be one of them. As HeadToHead inherits from UserControl that does not really seem to be the case, an instance of a UserControl should ideally never be static.
I'm making c# app where I need to access method in partial class from another class.
To be more specific I want to add items to listview from class that is different from partial class but in same namespace.
I tried like this:
public partial class Aa : Form
{
public static void UpdateListView(string[] array)
{
if (ProcessNetUsageList.InvokeRequired)
{
ProcessNetUsageList.Invoke(new Action<string[]>(UpdateListView), array);
}
else
{
ListViewItem item = new ListViewItem(array[0]);
for (int i = 1; i < 4; i++)
item.SubItems.Add(array[i]);
ProcessNetUsageList.Items.Add(item);
}
}
}
and then access it from another class like:
class Test
{
test()
{
ProgramName.Aa.UpdateListView(someArray);
}
}
But its giving an error because static method can only access static variables,and my listview isnt static(i created that listview in vs designer).
If i remove static keyword from method in partial class then i cant access it.I tried to create instance of partial class but without success.Any idea is welcome
note:Im using Invoke in my UpdateListView method because later that will be running on new thread
The nature of an object-oriented language is that objects don't have universal access to modify other objects. This is a good thing.
You've provided relatively little code so it's hard to provide a perfect answer here, but there are a few paradigms that resolve this issue.
One is to pass the instance to your test class, like this:
class Test
{
test(ProgramName.Aa form)
{
form.UpdateListView(someArray);
}
}
Or, if class test actually contains the ListView, you can pass that to a static method in Aa.
class Test
{
ListView someListView;
test()
{
ProgramName.Aa.UpdateListView(someListView, someArray);
}
}
Ultimately, you should think about the logical relationship between these objects to determine how these objects should communicate.
Remove the static keyword from UpdateListView, as you have done before. In test(), you need to instantiate Aa before you access UpdateListView.
Aa temp = new Aa()
You can then access the method by using
temp.UpdateListView(someArray);
I want to access my ViewModel from a class which is not the View. Is it OK if I do the following? Is this breaking the pattern?
namespace MyApp
{
public class GameView
{
protected new GameViewModel ViewModel
{
get { return (GameViewModel)base.ViewModel; }
}
}
}
// Derived class
namespace MyApp
{
public class InAppPurchase: GameView
{
public void BuyCoins()
{
ViewModel.PurchasedCoins += ViewModel.CoinsForSale;
}
}
}
If you want to access a ViewModel from whichever place you want you might want to send messages (MvxMessage) and handle them within the ViewModel (publish/subscribe with IMessenger). This is the proper way to communicate between ViewModels or ViewModels and other components like services in the Mvvm pattern.
I want main viewmodel to have a certain list, and then access from many other viewmodels.
For example, in MainViewModel.cs I will have a list of 50 numbers,
then in NumListViewModel.cs, I'd like to access it in order to show it as a list, and in AddNumViewModel.cs I'd like to be able to update that list.
It's been suggested that I use events / evenaggerator, which I did, but unfortunately, for all I know all I can do with it is send a num from one view to another and tell it to update the list, but the problem is, as the program grows, I will need to have a lot of subscribers in the main view model, and when something actually happens I will have to "publish" events according to the number of subscribers which makes it even harder to maintain.
I also found another answer, instructing to create an instance of anotherVM within the mainVM, with a parameter set to "this" which is a reference to the mainVM.
It works, but then again, it could get quite long.
So my question is, is there a better way to access a property from another VM?
Like literally have the an instance of the class that holds the list in the mainVM, and then just be able to update / access it from the other VMs, without having to explicitly program which VM can. Would make life so much easier.
In your answer, please try to avoid suggesting frameworks.
Although there are some really good ones, I want to be able to do at least that by myself.
For example:
MainVM.cs:
public class MainVM
{
List lst = new List(); //Let's just say it's full...
}
OtherVM.cs:
public class OtherVM
{
lst.Add(3);
}
PS: Yes I know it has been asked already, and yes I have done my research, BUT I the answers I found are too 'static', I guess?
If you want direct access to the list from an external ViewModel, then your options are to:
Pass the List to the OtherVM as a constructor argument or public property. Then the OtherVM can treat it like a member.
Pass the MainVM to the OtherVM as a constructor argument or public property. Then the OtherVM can access the List by first accessing the MainVM.
Example:
public class MainVM
{
public List<XX> MyList { get; set; }
}
public class OtherVM
{
public MainVM TheMainVM { get; set; }
public OtherVM(MainVM theMainVM)
{
TheMainVM = theMainVM;
// Access the MainVM's list
TheMainVM.MyList.Add(stuff);
}
}
Give the MainVM a static property called "Default" or "Instance," so you can access the static instance of MainVM from within OtherVM, without assigning it as a member field.
Example:
public class MainVM
{
private static MainVM _instance = new MainVM();
public static MainVM Instance { get { return _instance; } }
public List<XX> MyList { get; set; }
//other stuff here
}
//From within OtherVM:
MainVM.Instance.MyList.Add(stuff);