elo
elo

Reputation: 39

Make only one of many controls visible based on value of another control

I have a ComboBox bound to a collection of objects defined as this.

public class TierOption
{
    public string Option { get; set; }
    public Type DataType { get; set; }
}
public class TierOptions : ObservableCollection<Tier1Option>
{

}

I have 3 other controls related to this ComboBox, which are a TextBox, ComboBox, or a WPFToolKit:DatePicker.

I need to show only the related control which corresponds to the datatype(Type) of the object selected in the first ComboBox and neither of the others.

Pseudo Code Example: (Probably too close to butchered C# but hopefully it conveys the idea)

switch (ComboBox.SelectedItem.DataType)
{
     case String:
          TextBox.Visibility = Visibility.Visible;
          ComboBox.Visibility = Visibility.Hidden;
          DatePicker.Visibility = Visibility. Hidden;
     break;
     case DateTime:
          TextBox.Visibility = Visibility.Hidden;
          ComboBox.Visibility = Visibility.Hidden;
          DatePicker.Visibility = Visibility. Visible;
     break;
     <...so forth and so on...>
}

My attempts have resulted in very non-wpf looking convoluted messes which don't work regardless. Being new to wpf I'm trying very hard to stay true to the best design practices.

Thank you!

Upvotes: 3

Views: 2074

Answers (2)

paparazzo
paparazzo

Reputation: 45096

Bind to the detail visibility to ElementName=ComboBox Path=SelectedItem.DataType. And you will need to use a converter that returns visibility. You will need two converters return opposite answers. If you have more than 2 combination then some more in the line of Jonas.

I assumed Type was a system class and it appears to be a custom class. Extend that class to have additional properties. Even if Type was a system type you could just create a class that implements it and extend it.

   public Visibility TextBoxVisibility { get; }
   public Visibility ComboBoxVisibility { get; }
   ...

Then on TextBox bind the visibility

   Visisbility="{binding ElementName=Combobox Path=SelectedItem.DataType.TextBoxVisibility]";

Upvotes: 0

Jonas
Jonas

Reputation: 675

You can play with DataTemplate with DataType property

<...Resources>
    <DataTemplate DataType="{x:Type sys:String}">
        <TextBox Text="{Binding}"/>
    </DataTemplate>
    <DataTemplate DataType="{x:Type DateTime}">
        <DatePicker .../>
    </DataTemplate>
    ...
</...Resources>

<ContentControl Content="{Binding SelectedItem, ElementName=myComboBox}"/>

<ComboBox ItemsSource="{Binding ...}"/>

The code above is just the idea, you could have to make adjustements. For example you won't be able to modify a string item itself (you could have to encapsulate each item of your list)

If your list contains all items of the same type, you can use a ContentTemplateSelector on contentControl.

 ContentControl Content="{Binding SelectedItem, ElementName=YourCombBox}" ContentTemplateSelector="{StaticResource YourTemplateSelector}"

MSDN DOC about ContentControl.ContentTemplateSelector Property

Upvotes: 5

Related Questions