数据绑定ItemsControl内部的ItemsSource

本文关键字:ItemsSource 内部 ItemsControl 数据绑定 | 更新日期: 2023-09-27 18:21:31

当谈到wpf时,我仍然认为自己是一个初学者。我想知道两件事

  1. 我哪里出了问题或者
  2. 如何进行故障排除以找到解决方案

情境:[数据部分]我有:DataModel对象。DataFilter对象,它基本上是DataModels+添加函数的集合。和DataFiltersGroup,它在DataViewModel中使用,具有DataFilters的集合。我有一个DataViewModel对象,它基本上是一个可观察的项目集合。我想在项目控件中显示每个数据过滤器。

[当前解决方案]我已经构建了一个特殊的combo控件,它派生自combobox[基本上是一个按钮+combobox]。specialcombo在故意绑定时工作良好。所以我很有信心问题不在于特殊组合。当我将ItemsControl.ItemsSource属性设置为DataFilters的集合并创建SpecialCombo的DataTemplate时,组合框不会显示任何结果(如果没有Items,Special组合框将不会显示切换按钮,只显示按钮)。下面绑定的另一种方法(2)让我看到下拉切换按钮,但下拉是空的,但我知道它不应该是空的。

这是代码的摘要

public class DataModel :INotifyPropertyChanged
{
    //The Item!!
    public int Index {//Normal get set property}
    public string Name {//Normal get set property}
    public int Parent {//Normal get set property}
    public string FullName {//Normal get set property}
    public string DisplayName {//Normal get set property}
    public bool Static {//Normal get set property}
}
public class DataFilters : DataCollection
{
    public ObservableCollection<DataModel> CombinedData;
    public int FilterIndex{//Property... The index of the current item like Index for DataModel.}
    public string ParentName {//property ButtonContent item}
    public int SelectedItem {//Property}
}
//Used as part of DataVieModel.  Also responsible of building each DataFilters item and some other functions
public class DataFilterGroup : INotifyPropertyChanged
{
    public ObservableCollection<DataFilters> FullCollection;
}

WPF对象

<ItemsControl x:Name="PART_ListBox" HorizontalAlignment="Left" VerticalContentAlignment="Stretch" Margin="0">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

WPF加载的代码隐藏

//DVM = DataVieModel with some other objects.  Filters = DataFilterGroup
PART_ListBox.ItemsSource = DVM.Filters.FullCollection;
PART_ListBox.ItemTemplate = DataFilterTemplate;
//And DataTemplate (1) - shows no combobox
private static DataTemplate DataFilterTemplate
{
    get
    {
        DataTemplate DFT = new DataTemplate();
        DFT.DataType = typeof(DataFilters);
        FrameworkElementFactory Stack = new FrameworkElementFactory(typeof(VirtualizingStackPanel));
        Stack.SetValue(VirtualizingStackPanel.OrientationProperty, Orientation.Horizontal);
        FrameworkElementFactory Item = new FrameworkElementFactory(typeof(SpecialCombo));
        Item.SetValue(SpecialCombo.ButtonContentProperty, new Binding("ParentName"));
        Item.SetValue(SpecialCombo.ItemsSourceProperty, "CombinedData");
        Item.SetValue(SpecialCombo.DisplayMemberPathProperty, "DisplayName");
        Item.SetValue(SpecialCombo.SelectedValuePathProperty, "Index");
        Item.SetValue(SpecialCombo.SelectedValueProperty, "SelectedItem");
        //Item.SetValue(SpecialCombo.ToggleVisibleProperty, new Binding("ComboVisibility"));
        //Item.SetValue(SpecialCombo.SelectedValueProperty, new Binding("SelectedItem"));
        Stack.AppendChild(Item);
        DFT.VisualTree = Stack;
        return DFT;
    }
}    
//And DataTemplate (2) - shows combobox with no items in dropdown
private static DataTemplate DataFilterTemplate
{
    get
    {
        DataTemplate DFT = new DataTemplate();
        DFT.DataType = typeof(DataFilters);
        FrameworkElementFactory Stack = new FrameworkElementFactory(typeof(VirtualizingStackPanel));
        Stack.SetValue(VirtualizingStackPanel.OrientationProperty, Orientation.Horizontal);
        FrameworkElementFactory Item = new FrameworkElementFactory(typeof(SpecialCombo));
        Item.SetValue(SpecialCombo.ButtonContentProperty, new Binding("ParentName"));
        Item.SetValue(SpecialCombo.ItemsSourceProperty, new Binding("CombinedData"));
        Item.SetValue(SpecialCombo.DisplayMemberPathProperty, "DisplayName");
        Item.SetValue(SpecialCombo.SelectedValuePathProperty, "Index");
        Item.SetValue(SpecialCombo.SelectedValueProperty, "SelectedItem");
        //Item.SetValue(SpecialCombo.ToggleVisibleProperty, new Binding("ComboVisibility"));
        //Item.SetValue(SpecialCombo.SelectedValueProperty, new Binding("SelectedItem"));
        Stack.AppendChild(Item);
        DFT.VisualTree = Stack;
        return DFT;
    }
}    

数据绑定ItemsControl内部的ItemsSource

感谢punker 76在另一篇文章中,我重新构造了这个问题(这里->可以从ItemsControl的数据模板绑定一个组合框Itemssource吗),必须稍微完成以下操作。

数据过滤器应成为一个依赖对象,因此

public class DataFilters : DataCollection
// should become
public class DataFilters : DependencyObject

Observalbe集合也应该改变。所以

public ObservableCollection<DataModel> CombinedData;
// should become
public static readonly DependencyProperty CombinedData= DependencyProperty.Register("CombinedData", typeof(ObservableCollection<DataModel>), typeof(DataFilters), new FrameworkPropertyMetadata());
//and should become a property
public ObservableCollection<DataModel> CombinedData
{
    get { return (ObservableCollection<DataModel>)GetValue(CombinedDataProperty); }
    set { SetValue(CombinedDataProperty, value); }
}

然后,在DataTemplate文件中,应更改以下内容Item.SetValue(SpecialCombo.ItemsSourceProperty,"CombinedData");//应更改为Item.SetBinding(SpecialCombo.ItemsSourceProperty,new Binding("CombinedData"));

我还没有完成上面的全部代码,但我认为为了在DataTemplate中绑定combobox类型的项,应该需要所有以上的更改。