Closed SuperBrain closed 3 years ago
Have you read this page from the documentation? Define your own ViewManager which implements whatever strategy you want.
Thanks for pointing that out, but I'm well aware of it (hence mentioning the sample). My question here is, would it be possible to provide one of the following solutions:
1.
would mean adding a new feature while 2.
would be providing another sample. Either way, this would add more value to already great library.
You can write whatever mapper you need.
Would be really nice if Stylet had such feature without having to create your own ViewManager. I've faced a similar situation and ended up making multiple views due to the complexity of the viewmanager, to just add a few mappings. I would definitively use a feature like this if available, could be as simple as a dictionary that Stylet lookup before mapping things by itself.
due to the complexity of the viewmanager
The ViewManager is simple: for your case, you can override LocateViewForModel
or ViewTypeNameForModelTypeName
.
Stylet makes it easy to replace bits of the framework precisely so that you can do what you're asking, and so that I don't need to ship an infinitely-customisable ViewManager.
Stylet uses a convention-based approach, where the name of the view type is derived from the name of the ViewModel type. That, unfortunately, means you can't easily have multiple ViewModel types for a single view type: in order to do this, you need to introduce some other mechanism. There are many such mechanisms you could choose: you could use an attribute (and I've written a ViewManager which does this, see the samples), or you could add some extra conventions onto the name (SomeViewModel1 -> SomeView, etc), or some manual mapping, or... I don't think there's a best approach here, but it really is very easy to do something yourself.
One of the aims of Stylet is to be lightweight. That means not shipping the kitchen sink, and instead letting people customise the behaviour using a small amount of their own code.
Here's an example which maps ViewModel1
and ViewModel2
, etc, to View
. Note how it's almost fewer lines than setting up some configuration on an infinitely-configurable ViewManager would be:
public class MyViewManager : ViewManager
{
protected override string ViewTypeNameForModelTypeName(string modelTypeName)
{
return base.ViewTypeNameForModelTypeName(Regex.Replace(modelTypeName, @"\d+$", ""));
}
}
@canton7 excuse my ignorance are you saying I could technically do something like this:
public class MyViewManager : ViewManager
{
public Dictionary<string, string> Map { get; set; }
protected override string ViewTypeNameForModelTypeName(string modelTypeName)
{
if (Map.ContainsKey(modelTypeName))
{
return base.ViewTypeNameForModelTypeName(Map[modelTypeName]);
}
return base.ViewTypeNameForModelTypeName(modelTypeName);
}
}
Where map would be say
Map = new Dictionary<string, string>
{
{ "CustomerReportViewModel", "ReportViewModel" },
{ "CompanyReportViewModel", "ReportViewModel" },
{ "AccountReportViewModel", "ReportViewModel" },
};
Is that not what this technically does if I understood it right? https://github.com/canton7/Stylet/blob/master/Stylet/ViewManager.cs#L107
Yes, you could do exactly that, although it's mapping from ViewModel -> View of course, not ViewModel -> ViewModel (I'd use TryGetValue
instead of doing two lookups, but the result is the same). You'll need the fully-qualified names (including namespace).
NamespaceTransformations
are only for transforming namespaces -- they map e.g. SomeLibrary.SomeViewModel
to SomeApplication.SomeView
. You can see that they match the start of the ViewModel's type name, and end at a .
. This can be needed for the convention-based mapping that Stylet does out of the box.
Closing as no response
I would like to be able to tell Stylet which View should be created for which ViewModel.
I have a specific use-case where I would like to create multiple VMs but have them all use a single View.
I understand this could be done by subclassing the ViewManager. However, having a simple dictionary that can tell Stylet to create
MyView
for bothMyViewModel
andMyOtherViewModel
would be a nice feature.EDIT: Someone pointed this from samples, which seems to be what I need, but I don't know how I would use that?
EDIT 2: I see the Attribute in there but there's a couple of issues with it
AllowMultiple = false
suggests that only 1 ViewModel can be mapped to a single ViewWouldn't it be better if this attribute was applied to VMs, specifying the View that goes with them?