zmb
zmb

Reputation: 7867

Sharing views between similar WPF applications

I'm working with two WPF applications that share the same code base and perform largely the same functions. ApplicationA is targeted to power users and contains all the bells and whistles for every feature we support. ApplicationB is more of an end-user tool - it looks essentially the same, but some of the more advanced features are hidden from the user in order to keep things as simple as possible.

There are quite a few views that are almost identical in the two tools with the only difference being we hide a few of the controls in ApplicationB. The views are similar enough that it doesn't make sense to maintain a separate copy for each tool. Our viewmodels know which application they are running in, so we currently solve this by binding the visibility of the view elements to properties of the viewmodel.

View:

<SomeControl Visibility="{Binding Path=WhichApp}"> ...

View Model:

public Visibility WhichApp
{
    get
    {
        if (GetApp() == Apps.ApplicationB) return Visibility.Collapsed;
        else return Visibility.Visible;
    }
}

I don't like that the viewmodels are responsible for handling visibility, which is almost by definition a property of a view. This approach also limits the reusability of our viewmodels outside of these two tools.

I'm interested in any alternative solutions that will help me to share views between the two projects while still maintaining separation of concerns between the views and viewmodels.

Upvotes: 1

Views: 283

Answers (2)

Clever Neologism
Clever Neologism

Reputation: 1332

I agree that something this global to the app should not be contained in each ViewModel (DRY). This sort of thing belongs in a static resource in App.xaml (BTW, this isn't a bad way to accomplish any sort of global setting, like themes/skins, permissions/roles of the current user, etc.).

Simply create a static resource in App.xaml's Application.Resources of type Visibility, then bind it to the code-behind in App.xaml, using the existing code you have there.

Now, you have a one-time calculated and retrieved, well known place to access the application mode everywhere, and your view models don't have to reinvent the wheel.

Upvotes: 1

Magnus Lindhe
Magnus Lindhe

Reputation: 7317

I think you are on the right track. How about changing the property to PowerUserMode. I think the view model is responsible to tell the view if it should render itself for a power user or not. The view can still bind Visibility properties on controls to the PowerUserMode property using the BooleanToVisibilityConverter.

public bool PowerUserMode
{
    get
    {
        return GetApp() != Apps.ApplicationB;
    }
}

If you do not like the coupling to GetApp() and the Apps type you could just have the property be backed by a bool and let some other class set the PowerUserMode on the view model as appropriate.

Upvotes: 1

Related Questions