What is the most minimal way to dynamically interchange UIElement
s at a certain "slot" on the UI? I have a number of UIElement
s and based on some external databinding (e.g. a combobox selection) I want one of them to be shown and the one that was currently visible to be hidden. So the behavior is sort of like the TabControl
but without the tabstrip, the chrome and the tabitem instances. So I could actually use the TabControl
and override the control template. But is this really the most minimal approach?

- 3,741
- 12
- 49
- 72

- 48,890
- 37
- 186
- 278
6 Answers
<ContentControl Content="{Binding SomePropertyThatYieldsTheContent}"/>

- 175,602
- 35
- 392
- 393
-
Based on the answer to http://stackoverflow.com/questions/1287995 I think a ContentPresenter would be a better choice here. – Wilka Dec 23 '09 at 14:14
I don't know if this is the most succinct way, but if you are using a DataTemplate
, you could use DataTrigger
s (the assumption here is that the initial visibility is Collapsed
):
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>Text</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="TextEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>Logical</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="LogicalEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=SourceProperty.ValueType}">
<DataTrigger.Value>
<pm:ValueType>DateTime</pm:ValueType>
</DataTrigger.Value>
<Setter TargetName="DateEditor" Property="Visibility" Value="Visible" />
</DataTrigger>
...

- 3,741
- 12
- 49
- 72

- 12,007
- 2
- 44
- 61
-
This method works very well if you only have a couple of "modes", e.g. an "edit" mode and a "read only" mode. I like to set Visibility to either Visible or Hidden and have multiple elements in the same grid cell so you don't have other UI elements shift during your mode change. – Bryan Anderson Mar 18 '09 at 14:24
You have several options. As Bryan mentioned, Data Template Selectors can definitely work, although I've decided that they are frequently overkill. Take your example for instance - if you want to bind the visibility of an element to the selection in a ComboBox
, I would prefer a ValueConverter
instead. Pass the ComboBox.SelectedItem
to the Converter
and have it return a Visibility value:
public class MyObjectToVisibleOrCollapsed : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is MyObject)
{
var myObject = (MyObject)value;
if (myObject.SomeState)
{
return Visibility.Visible;
}
}
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
Now in your Window.Resources, create an instance of the ValueConverter
and Bind the Element to the ComboBox.SelectedItem
using the ValueConverter
instance:
<local:MyObjectToVisibleOrCollapsed x:Key="myObjectToVisibleOrCollapsed"/>
<DataTemplate x:Key="MyTemplate">
<TextBlock Text="{Binding Path=myText}"
x:Name="MyText"
Visibility="{Binding ElementName=MyComboBox, Path=SelectedItem, Converter={StaticResource myObjectToVisibleOrCollapsed}, Mode=Default}" />
</DataTemplate>
And of course you can reuse the ValueConverter
for all the elements in your DataTemplate
(and if there are a lot of them, then the Data Template Selector approach becomes more desirable).
[Disclaimer: the code above was hashed out from memory and not tested - it may need a little tweaking]

- 3,741
- 12
- 49
- 72

- 7,139
- 2
- 30
- 43
I create custom user controls for each possible 'view'.
Their visibility is changed using c#, thou. Little coding needed.
The primary reason for this approach is the ease of development — the designer focuses on particular view rather than the set of all posible controls that will be there.

- 5,167
- 3
- 43
- 70
Look into Data Template Selectors, Bea Stollnitz has a good post here. Basically you'll use a ContentPresenter
in each of your UI "slots" and then use the ContentTemplateSelector
property to define which template selector you'll use.

- 3,741
- 12
- 49
- 72

- 15,969
- 8
- 68
- 83
The way I do it is to layer the elements on top of each other and programatically change their Visibility property from Visible to Collapsed and back again as needed.

- 30,273
- 24
- 104
- 155
-
Our designers are not to good at c# but they are the ones to define the UI. – bitbonk Mar 18 '09 at 12:59