【问题标题】:C#/WPF/Caliburn.Micro - Combobox ItemsTemplate binding to anonymous type propertyC#/WPF/Caliburn.Micro - Combobox ItemsTemplate 绑定到匿名类型属性
【发布时间】:2019-02-10 07:29:22
【问题描述】:

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

用户使用一个表单来实例化不同的子类,其中包含一个组合框,用于选择要实例化哪个类(Combobox 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 填充了空白项(以及调试器中的不同集合),这让我觉得到目前为止一切都很好。

正如我之前所说,一些表单内容会根据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>

但我担心这是我能做到的,因为寻找不同的解决方案并没有让我有任何收获。

【问题讨论】:

  • 您的实际问题不是很清楚,您是否在将项目列表绑定到 ComboBox(即它是空白的?)或绑定表单的其他元素时遇到问题?
  • 组合框已绑定到集合,但我似乎无法处理绑定组合框项模板以显示列表项中的属性。关于表单元素的部分是因为我计划将表单元素绑定到 Combobox SelectedItem 的属性,这就是为什么我觉得有必要将 Combobox 直接绑定到类型列表,而不是例如辅助类。
  • 更新:好像我的问题出在数据绑定上。当我将 XAML 更改为简单的:&lt;Label Content="{Binding}" Margin="-5"/&gt; 而不是 &lt;Label Content="{Binding Path=ViewName}" Margin="-5"/&gt; 时,我得到了组合框中显示的类显示名称。

标签: c# wpf combobox caliburn.micro


【解决方案1】:

我的问题解决了。我将其回溯到填充 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

【讨论】:

    猜你喜欢
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    相关资源
    最近更新 更多