1
votes

I have a property on my ViewModel that is an enum:

ViewModel:

public MyViewModel {

    // Assume this is a DependancyProperty
    public AvailableTabs SelectedTab { get; set; } 

    // Other bound properties
    public string Property1 { get; set; }
    public string Property2 { get; set; }
    public string Property3 { get; set; }
}

public enum AvailableTabs {
    Tab1,
    Tab2,
    Tab3
}

I'd like to be able to bind SelectedIndex (or SelectedItem) of my TabControl to this property and have it correctly set the appropriate tab using a converter. Unfortunately, I'm a bit stuck. I know I can easily just use the SelectedIndex in my model, but I want the flexibility of re-ordering the tabs without breaking anything. I've given each TabItem a Tag property of the applicable enum value.

My XAML:

<TabControl Name="MyTabControl" SelectedIndex="{Binding SelectedTab, Converter={StaticResource SomeConverter}}">
    <TabItem Header="Tab 1" Tag="{x:Static local:AvailableTabs.Tab1}">
        <TextBlock Text="{Binding Property1}" />
    </TabItem>
    <TabItem Header="Tab 2" Tag="{x:Static local:AvailableTabs.Tab2}">
        <TextBlock Text="{Binding Property2}" />
    </TabItem>
    <TabItem Header="Tab 3" Tag="{x:Static local:AvailableTabs.Tab3}">
        <TextBlock Text="{Binding Property3}" />
    </TabItem>
</TabControl>

My problem is that I can't figure out how to get the TabControl into my converter so I can do:

// Set the SelectedIndex via the enum (Convert)
var selectedIndex = MyTabControl.Items.IndexOf(MyTabControl.Items.OfType<TabItem>().Single(t => (AvailableTabs) t.Tag == enumValue));

// Get the enum from the SelectedIndex (ConvertBack)
var enumValue = (AvailableTabs)((TabItem)MyTabControl.Items[selectedIndex]).Tag;

I'm afraid I might be overthinking it. I tried using a MultiValue converter without much luck. Any ideas?

2

2 Answers

0
votes

Instead of specifying the values in the XAML, I would bind ItemsSource to an array of values from your enum:

Code:

public AvailableTabs[] AvailableTabs => Enum.GetValues(typeof(AvailableTabs Enum)).Cast<AvailableTabs>().ToArray();

XAML:

<TabControl Name="MyTabControl" SelectedIndex="{Binding SelectedTab}" ItemsSource="{Binding AvailableTabs}" />
0
votes

You simply need a converter that casts the value to an index.

public class TabConverter : IValueConverter
{
    public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        return (int)value;
    }

    public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture )
    {
        return (AvailableTabs)value;
    }
}