开发者

WPF binding a path to the typename of a class

开发者 https://www.devze.com 2023-03-05 20:50 出处:网络
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 Advan

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消