有关绑定ListBox的疑问 [英] doubt about binding a ListBox

查看:71
本文介绍了有关绑定ListBox的疑问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我有一个内部具有子递归集合的集合.有点像休闲

Hi,

I have a collection which internally having sub collections recursively. its some thing like fallowing

class item
{
    public String Field1;
    public String Field2;
    public ObservableCollection<item> subitems=new ObservableCollection<item>();
}

public ObservableCollection<item> items=new ObservableCollection<item>();




这我准备与treeGridControl绑定.现在,需要将此集合与列表框绑定.如果我将此集合绑定到列表框,则仅显示1级对象.如果我想将所有项目递归绑定到列表框,我该怎么办.请帮帮我.

谢谢
Easwar.




this i prepared to bind with a treeGridControl. now there is a need to bind this collection with a list box. if i bind this collection to a list box it is showing only 1st level objects. if i want to bind all the items recursively to the listbox, how can i. please help me.

Thanks
Easwar.

推荐答案

这是一个完整的解决方案,其中分层数据源被展平并绑定到列表框:


步骤1:添加此扩展程序类.

Here is a complete solution whereby a hierarchical data source is flattened and bound to a listbox:


Step 1: Add this extension class.

// -----------------------------------------------------------------------
// <copyright file="Extensions.cs" company="">
// Source: http://darkorbit.net/articles/flatten-a-c-hierarchy.html
// </copyright>
// -----------------------------------------------------------------------
using System.Collections.Generic;
using System;

namespace HierarchicalData.Extensions
{
    public static class IEnumerableExtensions
    {
        /// <summary>
        /// Flattens an object hierarchy.
        /// </summary>
        /// <param name="rootLevel">The root level in the hierarchy.</param>
        /// <param name="nextLevel">A function that returns the next level below a given item.</param>
        /// <returns><![CDATA[An IEnumerable<T> containing every item from every level in the hierarchy.]]></returns>
        public static IEnumerable<T> Flatten<T>(this IEnumerable<T> rootLevel, Func<T, IEnumerable<T>> nextLevel)
        {
            List<T> accumulation = new List<T>();
            accumulation.AddRange(rootLevel);
            flattenLevel<T>(accumulation, rootLevel, nextLevel);
            return accumulation;
        }

        /// <summary>
        /// Recursive helper method that traverses a hierarchy, accumulating items along the way.
        /// </summary>
        /// <param name="accumulation">A collection in which to accumulate items.</param>
        /// <param name="currentLevel">The current level we are traversing.</param>
        /// <param name="nextLevel">A function that returns the next level below a given item.</param>
        private static void flattenLevel<T>(List<T> accumulation, IEnumerable<T> currentLevel, Func<T, IEnumerable<T>> nextLevel)
        {
            foreach (T item in currentLevel)
            {
                accumulation.AddRange(currentLevel);
                flattenLevel<T>(accumulation, nextLevel(item), nextLevel);
            }
        }
    }
}




步骤2:XAML. (如果需要,列表框的绑定方式可能会有所不同)




Step 2: The XAML. (The Listbox could be bound differently if you want)

<Window x:Class="HierarchicalData.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="MainWindow" 

        Height="600" 

        Width="640">
    
    <StackPanel x:Name="LayoutRoot" Background="White">
        <StackPanel.Resources>
            <HierarchicalDataTemplate x:Key="ChildTemplate">
                <TextBlock FontStyle="Italic" Text="{Binding Path=Field1}" />
            </HierarchicalDataTemplate>
            <HierarchicalDataTemplate x:Key="NameTemplate" 

            ItemsSource="{Binding Path=subitems}" 

            ItemTemplate="{StaticResource ChildTemplate}">
                <TextBlock Text="{Binding Path=Field1}" FontWeight="Bold" />
            </HierarchicalDataTemplate>
        </StackPanel.Resources>
        <StackPanel Orientation="Vertical">
            <TreeView Width="400"  

                          Height="300" 

                          ItemsSource="{Binding}" 

                          ItemTemplate="{StaticResource NameTemplate}" 

                          x:Name="myTreeView"/>
            <ListBox Width="400"  

                          Height="300" 

                          ItemsSource="{Binding}" 

                          ItemTemplate="{StaticResource NameTemplate}" 

                          x:Name="myListBox"/>
        </StackPanel>
    </StackPanel>
</Window>




步骤3:上课.请注意具有".Flatten"的行-这是执行魔术的位. (在这种情况下,为简单起见,后面的代码)




Step 3: The class. Note the line which has ".Flatten" - that''s the bit that does the magic. (In this case code behind for simplicity)

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using HierarchicalData.Extensions;

namespace HierarchicalData
{
    public partial class MainWindow : Window
    {
        static public ObservableCollection<item> Topics = new ObservableCollection<item>();
        static public List<item> FlatTopics = new List<item>();

        public MainWindow()
        {
            InitializeComponent();

            // Initialise some dummy data
            Topics.Add(new item("Orange", "Fruit"));
            Topics.Add(new item("Banana", "Fruit"));
            item DataGridTopic = new item("Gift Set", "Toiletries");
            DataGridTopic.subitems.Add(new item("Shampoo", "Toiletries"));
            DataGridTopic.subitems.Add(new item("Bath Bomb", "Toiletries"));
            DataGridTopic.subitems.Add(new item("Scented Candle", "Household"));
            Topics.Add(DataGridTopic);

            // Add the data to the controls
            myTreeView.DataContext = Topics;
            myListBox.DataContext = Topics.Flatten(n => n.subitems).Distinct().ToList();
            
        }
    }

    public class item
    {
        public string Field1 { get; set; }
        public string Field2 { get; set; }
        private ObservableCollection<item> subitemsValue = new ObservableCollection<item>();
        public ObservableCollection<item> subitems
        {
            get
            {
                return subitemsValue;
            }
            set
            {
                subitemsValue = value;
            }
        }
        public item() { }
        public item(string field1, string field2)
        {
            Field1 = field1;
            Field2 = field2;
        }
    }
}



希望那是你所追求的.如果有帮助,请标记为答案.

资料来源:


  • MSDN
  • 黑暗轨道


  • Hopefully that''s what you''re after. Please mark as answer if it helps.

    Sources:


    • MSDN
    • Dark Orbit

    • 这取决于您有多少个级别-是可预测的还是可变的,例如总是2个级别,有时2个,有时更多?

      如果您没有可预测的级别数,那么理想情况下您确实希望使用基于树的控件之类的东西.如果仅说两个级别,则可以将其绑定到一对列表框.

      有两种方法-一种是在 master/详细信息排列中将列表框分开/a>.在这里,您将在第一个列表中进行选择,第二个列表的内容将更改为该列表的内容.另一种方法是将一个列表框嵌套在另一个列表框内. br/>
      希望有帮助.
      This rather depends how many levels you have - is it predictable or variable, e.g. always 2 levels or sometimes 2 and sometimes more?

      If you don''t have a predictable number of levels then you ideally do want to use something like a tree-based control. If it''s say, only two levels, then you could feasibly bind it to a pair of listboxes.

      There are two approaches with this - one is to have the listboxes separate, in a master / detail arrangement. Here you would make a selection in the first list and the contents of the second would change to the contents of that one. The other approach is to nest one listbox inside the other.

      Hope that helps.


      这篇关于有关绑定ListBox的疑问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆