Hanch
Hanch

Reputation: 11

Conditional loading of WPF Control with only XAML code

Suppose i have a complex UI. Depending on the available MODEL data, some of the controls make no sense. I would like to have an option to 'disable' them. By 'disable' I mean that I don't want their DataBinding to happen as their ViewModel is unsafe\ undefined.

In this post, it was suggested to use DataContentSelector.

I wonder if there's a different approach that doesn't use code outside of the xaml. For example, an implementation using VisualState, where the VisualState will set the content to some empty box if the data is empty.

Thanks

Upvotes: 1

Views: 1050

Answers (3)

GazTheDestroyer
GazTheDestroyer

Reputation: 21261

<UserControl.Resources>
  ...
  <DataTemplate x:Key="someControl" ...>
  <DataTemplate x:Key="somePlaceholderControl" ...>

</UserControl.Resources>

<ContentControl Content="{Binding}">
  <ContentControl.Style>
    <Style TargetType="ContentControl">

      <Setter Property="ContentTemplate" Value="{StaticResource somePlaceholderControl}" />

      <Style.Triggers>
        <DataTrigger Binding="{Binding SomeTriggerProperty}" Value="SomeTriggerValue">
          <Setter Property="ContentTemplate" Value="{StaticResource someControl}" />
        </DataTrigger>
      </Style.Triggers>

    </Style>
  </ContentControl.Style>
</ContentControl>

Upvotes: 0

Mike Nakis
Mike Nakis

Reputation: 62045

The fully MVVM-compliant way in which I have been achieving this is as follows:

Say you have a view model of type MainViewModel which is being displayed by a view of type MainView.

MainView needs to conditionally show a sub-view of type SecondaryView, depending on the value of some controlling property in MainViewModel: when the controlling property has a certain value, the view is to be shown, when the controlling property has another value, the view is not to be shown, and when it is not shown, we do not want it to just be hidden, we want it to not even exist.

Introduce a new view model of type SecondaryViewModel. It can even be an empty class, though you will probably find some useful functionality to put in it.

In your MainViewModel introduce property MySecondaryViewModel of type SecondaryViewModel. This will be the controlling property. Initially, let the value of this property be null.

In the XAML of MainView, define a ContentControl as follows:

<ContentControl Content="{Binding MySecondaryViewModel}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type myViewModels:SecondaryViewModel}">
            <myViews:SecondaryView />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

So, now, the nullness of the controlling property MySecondaryViewModel controls the existence of SecondaryView:

  • For as long as the value of the controlling property is null, the framework does not create any view to display it, and the ContentControl is empty. (It has no content.)
  • If you assign an instance of SecondaryViewModel to the property, the framework will create an instance of SecondaryView to show it.
  • If you later set the controlling property to null again, the instance of SecondaryView will be destroyed.

Upvotes: 1

Ehsan Zargar Ershadi
Ehsan Zargar Ershadi

Reputation: 24833

I use this trick: ( sorry for bad English)

First i bind my DataContext to my VM and add a Converter to it

<Grid DataContext={Binding myvm, Converter={StaticResource mySwitchOfConverter}}

and in my converter i have something like this :

public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if(Util.SwitchContext == true)
               return value;
            return null;
        }

Util.SwitchContext is a static property witch i'll set and unset it in my code.

Upvotes: 0

Related Questions