I have a "design" problem. I don't know enough MVVM, I assume, to solve it elegantly.
I have TravelOrder objects. So of course I have a TravelOrder model.
I then have a "global" page where I list a number of different types of document (objects), including these TravelOrders.
On this "global" page I have a TapGestureRecognizer which executes a command which checks the type of document the user has swiped/clicked and executes this code:
else if (expenseOrTravelOrder.DocumentStyle == DocumentStyle.TravelOrder)
{
var thisTravelOrder = await travelOrdersService.GetTravelOrder(expenseOrTravelOrder.ID);
await Shell.Current.GoToAsync(nameof(TravelOrderDetails), true, new Dictionary<string, object>
{
{"TravelOrder", thisTravelOrder}
});
}
Now, the TravelOrderDetails page shows the details of the TravelOrder object nicely, as per the TravelOrder model.
But, you see, I need to reuse this TravelOrderDetails xaml view. I need it to be in EDIT mode, in NEW mode or in VIEW mode, depending on some other criteria.
So I have declared in a "commons" class this enum:
public enum DocumentMode
{
Edit,
New,
View,
}
and then I have modified the call above to be
else if (expenseOrTravelOrder.DocumentStyle == DocumentStyle.TravelOrder)
{
var thisTravelOrder = await travelOrdersService.GetTravelOrder(expenseOrTravelOrder.ID);
thisTravelOrder.DocumentMode = Commons.DocumentMode.Edit;
await Shell.Current.GoToAsync(nameof(TravelOrderDetails), true, new Dictionary<string, object>
{
{"TravelOrder", thisTravelOrder}
});
}
(see ? I have added the line which sets the DocumentMode (in this case, Edit)).
And then I plan to somehow detect in the constructor of the TravelOrderDetails view the type of document the view is getting (i.e. New, or Edit, or View) and show/hide controls accordingly).
(BTW, I cannot do it yet in the constructor, I don't know how, I would have liked to do the controls manipulation in C# code rather than in xaml with triggers - I guess I need some event like Load, or similar, because in the constructor
public TravelOrderDetails(TravelOrderDetailsViewModel viewModel)
{
InitializeComponent();
BindingContext = viewModel;
}
my viewModel.TravelOrder is always null)
But.... and this is my main question: should the DocumentStyle property belong to the TravelOrder model ? I am thinking that this should NOT be in the model, and it should better be passed to the call above as a parameter to the TravelOrderDetails view, something like so:
(expenseOrTravelOrder.DocumentStyle == DocumentStyle.TravelOrder)
{
var thisTravelOrder = await travelOrdersService.GetTravelOrder(expenseOrTravelOrder.ID);
await Shell.Current.GoToAsync(nameof(TravelOrderDetails), true, new Dictionary<string, object>
{
{"TravelOrder", thisTravelOrder} //and pass the DocumentMode parameter to TravelOrderDetails somehow.
});
So: - Should the Edit/New/View parameter belong to the TravelOrder model ? - If not, how could I pass it in the call above ? How do I add a parameter to this call ?
await Shell.Current.GoToAsync(nameof(TravelOrderDetails), true, new Dictionary<string, object>
{
{"TravelOrder", thisTravelOrder}
});
Should I say
await Shell.Current.GoToAsync(nameof(TravelOrderDetails), true, new Dictionary<string, object>
{
{"TravelOrder", thisTravelOrder},
{"DocumentStyle", Commons.DocumentMode.Edit},
});
?
Could this stand to scrutiny from an architectural/design point of view ?
Thank you !
Alex