WPF binding a path to the typename of a class
Using WPF, I want to bind the header of a GroupBox to the typename of a polymorphic class. So if I have a class called Element, and two classes that derive from Element, such as BasicElement and AdvancedElement, I want the header of the GroupBox to say "BasicElement" or "AdvancedElement". Here is the xaml I am using for the GroupBox. It's part of a DataTemplate being used by an ItemsControl. I'm hoping for something in place of Path=DerivedTypeNameOf(group) in the XAML, where group is each group in the groups array.
Note that the ObjectInstance of TheData is being set to a valid instance of GroupSet which holds an array of some BasicGroups and AdvancedGroups.
Here are the pertinent code-behind classes:
public class Group
{
public string groupName;
public string df_groupName
{
get { return this.groupName; }
set { this.groupName = value; }
}
}
public class BasicGroup : Group
{
}
public class AdvancedGroup : Group
{
}
public class GroupSet
{
public Group [] groups;
public Group [] df_groups
{
get { return this.groups; }
set { this.groups = value; }
}
};
Here's the XAML:
<UserControl.Resources>
<ResourceDictionary>
<ObjectDataProvider x:Key="TheData" />
<DataTemplate x:Key="GroupTemplate">
<GroupBox Header="{Binding Path=DerivedTypeNameOf(group)}">
<TextBox Text="This is some text"/>
</GroupBox>
</DataTemplate>
</ResourceDictionary>
</UserControl.Resources>
<ItemsControl ItemsSource="{Binding Source={StaticResource TheData}, Path=groups}" ItemTemplate="{StaticResource开发者_如何学运维 GroupTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
You could always use a ValueConverter to get the type:
public class TypeNameConverter : IValueConverter {
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture) {
return value.GetType().Name;
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture) {
throw NotImplementedException();
}
}
That would allow you to have any type in your collection without any need for it to implement a property to get the value. Otherwise, just do as David says and implement a property to give the result. You wouldn't even need to implement it in every class if there is general inheritance from a base class. Just implement it in the base with GetType().Name and you'll always get the correct value.
Why not just add
public abstract string DerivedTypeName { get; set; }
to your base class and override it for each derived type then you are simply binding to a string.
精彩评论