【问题标题】:DataBinding an ItemsSource inside an ItemsControl在 ItemsControl 中对 ItemsSource 进行数据绑定
【发布时间】:2017-02-18 20:57:11
【问题描述】:

在 wpf 方面,我仍然认为自己是一名初学者。我想知道两件事

  1. 哪里出错了或者
  2. 如何排除故障才能找到解决方案。

情况:[数据部分]我有: 数据模型对象。 DataFilter 对象,它基本上是 DataModels + 附加功能的集合。和 DataFiltersGroup,它在 DataViewModel 中使用并具有 DataFilters 的集合我有一个 DataViewModel 对象,它基本上是一个可观察的项目集合。我想在 Itemscontrol 中显示每个 DataFilter。

[当前解决方案] 我已经构建了一个从组合框派生的特殊组合控件 [基本上是按钮 + 组合框]。故意绑定时,specialcombo 可以正常工作。所以我相当有信心问题不在于特殊组合。当我将 ItemsControl.ItemsSource 属性设置为 DataFilters 的集合并制作 SpecialCombo 的 DataTemplate 时,组合框不显示任何结果(如果没有 Items,则特殊组合不会显示切换按钮 - 只会显示按钮)。另一种方法 - 下面绑定的方法 (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;
    }
}    

【问题讨论】:

  • 我真的没想到这个问题这么复杂,但似乎没有人能回答它:(

标签: c# wpf data-binding itemscontrol


【解决方案1】:

感谢 punker 76 在另一篇文章中我对问题进行了重构(此处 -> Can one bind a combobox Itemssource from a datatemplate of a ItemsControl),必须完成以下工作。

DataFilters 因此应该成为一个依赖对象

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 中绑定一个组合框类型项,应该需要所有上述更改。

【讨论】:

    猜你喜欢
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-21
    • 2010-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多