View which manages some generic variable object with Prism - wpf

I'm working with Prism and I have a view which will manage some variable entity objects.
E.g.: Now I'm managing a User, but later I would manage a Customer using the same view (I already have the solution to achieve it ... link 1 - link 2).
This object (or the object type) to be managed must be declared and passed by me.
In a common way, I could pass the object type through a parameter on the constructor, but as I'm using Prism and I don't directly use the constructor of the Views or ViewModels.
Here's a snippet of how I currently "invoke" my views:
var regionManager = ServiceLocator.Current.GetInstance<IRegionManager>();
var viewUri = new Uri("MyGenericView", UriKind.Relative);
regionManager.RequestNavigate("AreaTrabalho", viewUri);
The problem is: I can't pass a parameter. Is there a way of passing that parameter or an alternative way of doing this (without a kind of ugly hack)?

You can implement INavigationAware on your VM's and pass parameters inside query string in your regionManager.RequestNavigate call

Related

SilverStripe: Creating form fields statically and via the 'new' keyword

I've been trying to find some info on difference between instantiating form fields through static method and the new keyword. Can somebody tell me what are the practical implications, limitations, between new MyFormField and MyFormField::create() esp. with regards to SilverStripe
Using the create factory method would check for overloads (set via Object::useCustomClass()) and return an instance of the custom class in that case.
This method first for strong class overloads (singletons & DB
interaction), then custom class overloads. If an overload is found, an
instance of this is returned rather than the original class. To
overload a class, use Object::useCustomClass()
So using the create method rather than instantiating the Object yourself would provide a possibility to overload the used Class without altering the code.
see
http://api.silverstripe.org/3.1/class-Object.html#_useCustomClass
http://api.silverstripe.org/3.1/class-Object.html#_create

Passing data from main application view to some subviews

Please consider following Backbone application structure:
AppView
Subview
FirstSubviewInQuestion
Subview
Subview
SecondSubviewInQuestion
Application view creates and stores a collection of special items. At a certain time the first and the second subview needs to get access to that collection. Now what is the best way to pass the collection it to them?
I myself see some ways, yet each has a downside:
1) Create instance of that collection not inside the App View but even more globally and then pass it around as dependency (project uses RequireJS; so it would be passed to AppView and both Subviews).
Downsides: app view is supposed to be the top most element in application. Yet suddenly we have some instances of collections floating above.
2) Or I can do following:
// some subview
var collection = {};
Backbone.trigger( "item:getSpecialItems", collection);
// now the collection has data
// app view
this.listenTo( "item:getSpecialItems", function(obj) {
// copy collection to passed object
_.extend(obj, this.specialCollection);
});
Downsides: we are triggering a global event. We know that only the app view would respond, but it feels like a bad design. Plus, this way to pass the collection seems like a hack.
Maybe there are some other clever ways to do it?
I would say #1.
app view is supposed to be the top most element in application
Right, but you're talking about (I think) a Collection, not a View; the two are totally separate parts of your application (in MVC the first is the "M" and the second is the "V"). By definition, if your views are driven by your data, the data must be "higher" (in the dependency tree) than any view, so I don't see anything wrong with that approach.
If your goal is to get a shared instance of the collection, my approach would be to pass that down from the parent to "subview" and from subview into its children. However, I wouldn't necessarily use require to pass around a singleton of this collection.
You could also pull out all of the logic from the view regarding the special methods for "creation and storage of special objects" into a helper class whose sole domain is just this. That helper then becomes a utility available from outside the view hierarchy, perhaps even globally or via require.

when to use defaults vs the initialize constructor on a model

So, I'm trying to learn how to use Backbone and I keep switching back and forth between using the defaults object and the initialize method. If I use the method, it's with "this.set()" to set attributes, etc. Otherwise those attributes are set in the default object.
I've looked around on google and I can't seem to find a recommended way or "common" pattern of when to use defaults or when to use initialize. I can make my code work both ways and both yield an object with the desired attributes, but it bugs me because i'm unsure if i'm using it incorrectly.
You would use the defaults object for all "static" data as you can only define them once for a model class. You will need the initialize method if you have to add dynamic per instance properties. For example:
initialize: function() {
this.set({displayName: this.get('firstname') + this.get('lastname')});
}

Have a module dependent Injection for State in PRISM WPF application

hi we have a PRISM WPF MVP application, we would like to have a state to share data between the views in the same module. Since PRISM by default doesnt have a state, was wondering if there is any way i could implement this. Presently i have injected a State with Dictionary as back-store, but the problem is its Global i.e available across the modules. i would really like to scope this injection being module specific.
I believe unity allows registering different classes to the same interface based on name, not sure if the only choice i have is to leverage that for my scenario.
Any help would be great! Thanks!
-ioWint
I would agree, scoping Unity's type registration with the ModuleName would be a place to start.
Inject a local(module level) state object into all the views that want to have share state. If the interface that defines the state object is local to your module then other modules won't be able to reference the state object because they can't reference the interface.
So: If Module A has 3 views that take an object implementing IStatefulContainer (also declared in Module A) and IStatefulContainer is registered with Unity using RegisterInstance rather than just RegisterType you'll have a singleton that is scoped to the module.
My preference would be to have a "State" service that managed state. This could allow you to add more functionality here if you needed it and is a more "Prismy" approach.
EDIT
If you're using this state object across modules then you can do the following:
1)Put the interface in an assembly that will be referenced by any module that wants to use it.
Assembly A
public interface IBlah
{
string Add(string stateKey, string stateValue);
}
Assembly B (referencing Assembly A)
public class Module:IModule
{
private IUnityContainer _container;
public Module(IUnityContainer container)
{
_container=container;
}
public void Initialize()
{
IBlah blah1=new BlahContainer();
IBlah blah2=new BlahContainer();
_container.RegisterInstance<IBlah>(blah1,"BlahContainer1");
_container.RegisterInstance<IBlah>(blah2,"BlahContainer2");
}
}
Module C(references assembly A)
_container.Resolve<IBlah>("BlahContainer1");
_container.Resolve<IBlah>("BlahContainer2");
Basically, we define the interface in an assembly we're happy to share between modules. Some projects have "Infrastructure" or Common assemblies that contain service interfaces that are used by other modules - this would fit well here.
We then have our module reference the assembly with the contract in it.
At the moment I'm relying on "magic strings" here but there are lots of ways around this.
Hope this is a little more clear.
thanks for your updated solution. I was trying to avoid a name based Unity registration, which would force my Presenter in knowing the Modules State registration Key.
I was reading stackoverflow posts on Unity and found the discussion over here Is it possible to override parameter values when using Method Injection with Unity? .
After couple of hours of trial and errors, i ended up achieving the desired functionality.
What i have done:
I have a BaseClass for my Modules -> BaseModule:IModule i have a State Property in it which conforms to my IStateService defined in the Infrastructure.Interface. I Instantiate this State property in the BaseModule() constructor.
Note: to go with this approach i have to make my Presenter's have a public IStateService State; property..
At the time of registering the Presenter in the module, i am specifying
<UnityContainer>.RegisterType<MyPresenter, new InjectionProperty("State", State).
Am overriding a public property in Presenter which has name "State" with the State instance value defined in the Module.
this way i am able to get the Modules State as the State for each of the View's presenter.
Thanks guys for directing me towards a solution.
-ioWint

WP7 NavigationService.Navigate pass a pointer without using global variables?

I am navigating to page X in WP7. I have an object (let's call it banana) in my ViewModel, which is where the NavigationService.Navigate call is being made. Page X needs a reference to the banana. How can I do that?
The answer to this question recommends using the global App class. Not a good option for me because I might have multiple instances of the class of page X, and I wouldn't want to confuse other instances if they are later navigated to.
I would also prefer not to have to serialize the banana.
If there could be multiple instances of the page then you'll need to pass any parameters it needs as part of the querystring in the Uri you use for navigation.
You can either use the query string (to send the id, for example) as suggested by #Matt, and you could also send the object itself via a message for example, you can use the Messenger class from MVVM Light for that.
Hope this helps :)

Resources