C#/ WPF / Caliburn.Micro-组合框ItemsTemplate绑定到匿名类型属性

时间:2019-02-10 07:29:23

标签: c# wpf combobox caliburn.micro

背景:我正在使用C#,WPF和Calburn.Micro创建一个面向GUI的应用程序,该应用程序具有一组预定义的多态对象,这些对象由继承自抽象父类的子类实现。

用户使用表单实例化不同的子类,该表单包含一个组合框以选择要实例化的类(组合框SelectedItem也计划根据所选类型的属性来触发更改表单内容)。

我设法使用以下方法将所有继承的子类带入BindableCollection中:

    private void LoadSubClasses()
    {
        Type _parentClass = typeof(ParentClass);
        Assembly assembly = Assembly.GetExecutingAssembly();
        Type[] _types = assembly.GetTypes();

        IEnumerable<Type> SubClassesIEnumerable = _types.Where(t => t.IsSubclassOf(_parentClass));

        foreach (var _subclass in SubClassesIEnumberable)
        {
            SubClassesColletion.Add(_subclass);
        }
    }

    private BindableCollection<Type> _subClassesCollection = new BindableCollection<Type>();
    public BindableCollection<Type> SubClassesCollection
    {
        get { return _subClassesCollection; }
        set { _subClassesCollection = value; }
    }

在运行时,我可以看到由空白项目(以及调试器中的不同集合)组成的组合框,到目前为止,我的工作是如此顺利。

如前所述,某些表单内容将根据Combobox的SelectedItem进行更改,因此我认为正确的方向是将Combobox项设置为类型,然后将不同的元素绑定到所选类型的属性。 我正在尝试使用ItemsTempalte来实现这一点,首先从“子类选择器”组合框显示一个抽象属性(称为“ ViewName”),该属性将被所有子类覆盖:

        <ComboBox x:Name="SubClassesCollection" Height="23" Margin="5,0,5,0">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <Label Content="{Binding Path=ViewName}"  Margin="-5"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

但是我担心这是我所能做到的,因为寻找不同的解决方案并不能帮助我。

1 个答案:

答案 0 :(得分:0)

我的问题已解决。我将其回溯到填充IEnumerable的LoadSubClasses方法,并将其完全更改为:

        public void LoadSubClasses()
    {
        IEnumerable<ParentClass> subClassesIEnumerable = typeof(ParentClass)
            .Assembly.GetTypes()
            .Where(t => t.IsSubclassOf(typeof(ParentClass)))
            .Select(t => (ParentClass)Activator.CreateInstance(t));

        foreach (ParentClass _subClass in subClassesIEnumerable)
        {
            _subClassesCollection.Add(_subClass);
        }
    }

    private BindableCollection<ParentClass> _subClassesCollection = new BindableCollection<ParentClass>();
    public BindableCollection<ParentClass> SubClassesCollection
    {
        get { return _subClassesCollection; }
        set { _subClassesCollection = value; NotifyOfPropertyChange(() => SubClassesCollection); }
    }

如果我错了,请纠正我,但我相信我的第一次尝试将system.runtimetypes返回给IEnumerable,这对我来说是行不通的。 新的LINQ代码为每个子类返回一个实例化的对象,该对象可以放入BindableCollection(而不是BindableCollection)中,并且数据绑定可以正常工作。

为在此处回答问题的人提供的支持:Get all inherited classes of an abstract class