Reputation: 7683
I've got a TabControl that is bound to its viewmodel Items property:
<TabControl ItemsSource="{Binding Items}"/>
This is the viewmodel class:
public class ViewModel
{
public ObservableCollection<object> Items { get; } = new ObservableCollection<object>();
public ViewModel()
{
Items.Add(new Person() { FirstName = "Alan", LastName = "Turing" });
Items.Add(new Car() { ModelName = "Fiesta", Manifacturer = "Ford" });
}
}
Items
's type is ObservableCollection<object>
; this is because each tab represents a different kind of object, in this example a Person and a Car.
I want to bind the tab's header to a text that is not available as a property of the bound classes, let say a manually provided header.
For example, I would like the first tab to have the text "Person" as header and the second to have the text "Car" as header:
I thought of:
A Dictionary<object, string>
defined at the viewmodel level, let's call it Headers.
Each time i add an object to the collection, i would also add an Header to the Headers dictionary. Its key would be the object itself.
Person p = new Person() { FirstName = "Alan", LastName = "Turing" };
Headers.Add(p, "Person");
Items.Add(p);
But how to write the binding expression then?
<TabControl ItemsSource="{Binding Items}">
<TabControl.ItemTemplate>
<DataTemplate>
<Label Content="{Binding ????????}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Even if possible, this solution seems to be not very 'binding-friendly'.
There seems to be two problems here: dynamically attach an information to an instance, and access it via binding.
Any ideas?
The code, for completeness. My classes:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Car
{
public string ModelName { get; set; }
public string Manifacturer { get; set; }
}
My DataTemplate, defined in the <Winodow.Resources>
tag.
<DataTemplate DataType="{x:Type local:Person}">
<StackPanel>
<Label Content="{Binding FirstName}"/>
<Label Content="{Binding LastName}"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Car}">
<StackPanel>
<Label Content="{Binding Manifacturer}"/>
<Label Content="{Binding ModelName}"/>
</StackPanel>
</DataTemplate>
Upvotes: 0
Views: 522
Reputation: 2868
You can also override the ToString()
method for your model classed and return your friendly name from there.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return "Person";
}
}
Template
<TabControl ItemsSource="{Binding Items}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
Upvotes: 1