I do have a ListDetailsView
showing some data (lets say Company
as a simple example here). Normally the details of a Company
are shown as readonly. However, via the ListDetailsView.DetailsCommandBar
it is possible to edit a Company
(and also add a new Company
). A clear separation between view and edit mode seems to be a good choice for the UI. I'm using a UserControl
to show details of a Company
.
So here are my questions:
CompanyDetailsControl
and a CompanyDetailsEditControl
and select between the two (both using the same CompanyDetailsViewModel
). There are other solutions as well, for example, the CompanyDetailsControl
could handle the edit- and view-mode internally.UserControl
, how can that be realized with the ListDetailsView.DetailsTemplate
? I though it would be easy to use a DataTemplateSelector
here, but that is only available for the ItemTemplate
.Not sure what code to provide to clarify my questions. So in case you need any code to better understand my question please leave a comment.
Note: I have never worked with UWP app, only applying MVVM pattern from WPF.
Straight line where the split should happen is not drawn. It often depends on the developer himself, which framework is used and more.
Me personally would go in way where UI handles UIs' things
and ViewModel handles data only
. That means the view is responsible for showing you the controls you are expecting to see/control the application. And when the view learns that property was changed
, it should update how it looks.
Since the point we know the app will have edit
& readonly
modes, we should prepare all necessary UI components (UserControls
, Pages
, ...) to handle both those states. They would be binded to ViewModel
that have base in BaseViewModel
that already have this edit variable inside. So that each UI component know it can work with that.
Base view model:
abstract class BaseViewModel : INotifyPropertyChanged
{
private string mIsInEditMode;
public string IsInEditMode
{
get { return mIsInEditMode; }
set
{
if(mIsInEditMode == value) return;
mIsInEditMode = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(IsInEditMode));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
All "normal" ViewModels inherit from it:
class CompanyViewModel : BaseViewModel
{ /* props and logic of company */ }
UI component (UserControl
) would have either trigger (<Style.Triggers/>
) or binded properties Visibility
and IsEnabled
to the BaseViewModel
. Those bindings would handle this logic of showing/hiding and you have potential to control whole layouts, hide controls etc.
<UserControl d:DataContext="{x:Bind local:CompanyViewModel}">
<UserControl.Resources>
<local:BoolInverterConverter x:Key="BoolInvert"/>
</UserControl.Resources>
<Grid>
<Grid IsVisible="{Binding IsInEditMode}" IsEnabled="{Binding IsInEditMode}">
<!-- Controls for edit mode -->
</Grid>
<Grid IsVisible="{Binding IsInEditMode, Converter={StaticResource BoolInvert}}"
IsEnabled="{Binding IsInEditMode, Converter={StaticResource BoolInvert}}">
<!-- Controls for readonly mode -->
</Grid>
</Grid>
</UserControl>
Note: I've used property IsVisible
, You would actually use Visibility
with some custom converter.