1

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:

  1. Where should the differentiation between view- and edit-mode happen? I thought it is a good idea to have a 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.
  2. Assuming that it is a good idea to switch between two 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.

Jan Suchotzki
  • 1,406
  • 12
  • 24
  • 1
    Q1: There are several ways how to handle this and it is clearly on the intetion of developer/author to decide "how to do that"/"how it should look". E.g. You can have `bool` property in single viewmodel an switch it around on edit, bind all controls (or parent `groupBox`) to `IsReadOnly` and let it do the work. It depends what suits you the best ~ mentioned approach of exchanging view could work. :) Per me Q1 is too broad for this site. – Tatranskymedved Oct 04 '21 at 10:09
  • @Tatranskymedved I agree to some extend. 1. I thought that this is such a basic scenario that there is a default way of handling this and I simply couldn't find it. 2. documentation / examples for winui3 are few. So how to solve it with that technology? Again some best practice would be highly appreciated – Jan Suchotzki Oct 04 '21 at 10:26
  • 1
    Jan, I put "my opinion" into answer, hope it will help you decide. I think it might be worth putting this question to https://softwareengineering.meta.stackexchange.com/ , where people are discussing "architecture of the code" and "how to get different parts together" over "small-ish programming topics" (SO). – Tatranskymedved Oct 04 '21 at 11:15

1 Answers1

1

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.

Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47
  • That's great advice! I'll not mark your answer as accepted, because I hope to get some WinUI 3 specific answer here. As it looks like this will not happen, I'll accept your answer in a few days. – Jan Suchotzki Oct 08 '21 at 10:06