none
多级列表分组数据绑定 RRS feed

  • 问题

  • 场景:

    有2个大目录(DIR_X,DIR_Y),每个目录都有cn和en打头子目录,每个子目录同样有cn和en打头的子目录,一共3层。

    第一层:下拉列表显示2个大目录,通过下拉列表选择

               public ObservableCollection<DIRS> TwoDirList { get; set; }

    第二层:ListBox1显示第一层子的目录,通过分组(cn和en)

    第三层:ListBox2显示第二层子目录,通过分组(cn和en)

    public class DIRS
    {
        public string Name { get; set; }
        public ObservableCollection<DIR1> Dirs_1 { get; set; }
    }
    
    public class DIR1
    {
        public string Name { get; set; }
        public ObservableCollection<DIR2> Dirs_2 { get; set; }
    }
    
    public class DIR2
    {
        public string Name { get; set; }
    }
    

    如何使用XAML进行数据绑定到TwoDirList上,通过下拉列表的选择后,ListBox1和ListBox2跟随变化?

    2018年5月31日 0:59

答案

  • Hi,

    试一下这个:

    <Window x:Class="WpfApp2.Window4"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp2"
            mc:Ignorable="d"
            Title="Window4" Height="450" Width="800">
        <Grid>
            <StackPanel Margin="10">
                <ComboBox ItemsSource="{Binding DIRSs}"
                  DisplayMemberPath="Name"
                  SelectedItem="{Binding SelectedDIRS}" >
                </ComboBox>
    
                <ListBox ItemsSource="{Binding DIR1s}" Margin="0 5 0 0" Height="100">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
    
                <ListBox ItemsSource="{Binding DIR2s}" Margin="0 5 0 0" Height="263">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </Window>

    C#:

    namespace WpfApp2
    {
        /// <summary>
        /// Interaction logic for Window4.xaml
        /// </summary>
        public partial class Window4 : Window
        {
            public Window4()
            {
                InitializeComponent();
                this.DataContext = new ViewModel();
            }
        }
    
        public class ViewModel : INotifyPropertyChanged
        {
            public ViewModel()
            {
                this.DIRSs = new List<DIRS>()
                  {
                    new DIRS(){ Name = "Folder1",
                    Dirs_1 = new List<DIR1>()
                    {
                        new DIR1(){ Name = "CN-Sub11" },
                        new DIR1(){ Name = "CN-Sub12" },
                        new DIR1(){ Name = "EN-Sub11" },
                        new DIR1(){ Name = "EN-Sub12" }
                    },
                    Dirs_2=new List<DIR2>
                    {
                        new DIR2(){Name="CN-Sub11-11"},
                        new DIR2(){Name="CN-Sub11-12"},
                        new DIR2(){Name="CN-Sub12-11"},
                        new DIR2(){Name="CN-Sub12-12"},
                        new DIR2(){Name="EN-Sub11-11"},
                        new DIR2(){Name="EN-Sub11-12"},
                        new DIR2(){Name="EN-Sub12-11"},
                        new DIR2(){Name="EN-Sub12-12"}
                    }
                    },
                    new DIRS(){ Name = "Folder2",
                    Dirs_1 = new List<DIR1>()
                    {
                        new DIR1(){ Name = "CN-Sub21" },
                        new DIR1(){ Name = "CN-Sub22" },
                        new DIR1(){ Name = "EN-Sub21" },
                        new DIR1(){ Name = "EN-Sub22" }
                    },
                    Dirs_2=new List<DIR2>
                    {
                        new DIR2(){Name="CN-Sub21-11"},
                        new DIR2(){Name="CN-Sub21-12"},
                        new DIR2(){Name="CN-Sub22-11"},
                        new DIR2(){Name="CN-Sub22-12"},
                        new DIR2(){Name="EN-Sub21-11"},
                        new DIR2(){Name="EN-Sub21-12"},
                        new DIR2(){Name="EN-Sub22-11"},
                        new DIR2(){Name="EN-Sub22-12"}
                    }
                    }
                  };
                
                this.SelectedDIRS = this.DIRSs[0];
            }
            public IList<DIRS> DIRSs { get; set; }
            public ICollection<DIR1> DIR1s { get; set; }
            public ICollection<DIR2> DIR2s { get; set; }
            private DIRS _selectedDIRS;
            public DIRS SelectedDIRS
            {
                get
                {
                    return _selectedDIRS;
                }
                set
                {
                    _selectedDIRS = value;
                    OnPropertyChanged("SelectedDIRS");
                    this.DIR1s = _selectedDIRS.Dirs_1;
                    this.DIR2s = _selectedDIRS.Dirs_2;
                    OnPropertyChanged("DIR1s");
                    OnPropertyChanged("DIR2s");
                }
            }
            
            public DIR1 SelectedDIR1 { get; set; }
    
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(name));
            }
            #endregion
        }
    
        public class DIRS
        {
            public string Name { get; set; }
            public ICollection<DIR1> Dirs_1 { get; set; }
            public ICollection<DIR2> Dirs_2 { get; set; }
        }
    
        public class DIR1
        {
            public string Name { get; set; }
            public DIRS DIRS { get; set; }
        }
    
        public class DIR2
        {
            public string Name { get; set; }
            public DIRS DIRS { get; set; }
        }
    
    }

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 oneonce 2018年6月25日 6:10
    2018年6月7日 9:39

全部回复

  • 你好,

    >>如何使用XAML进行数据绑定到TwoDirList上,通过下拉列表的选择后,ListBox1和ListBox2跟随变化?

    不知道你的ListBox2显示第二层子目录是显示所有的呢,还是根据选中显示子的部分。

    另外下面有一个双层联动的例子你可以参考一下(如果是三层的话,可以参考修改一下):

    #Xaml

    <Window x:Class="ColeWPFSample.ComboboxSample.Window2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:ColeWPFSample.ComboboxSample"
            mc:Ignorable="d"
            Title="Window2" Height="450" Width="800">
        <Grid>
            <StackPanel Margin="10">
                <ComboBox ItemsSource="{Binding DIRSs}"
                  DisplayMemberPath="Name"
                  SelectedItem="{Binding SelectedDIRS}" />
    
                <ComboBox ItemsSource="{Binding DIR1s}"
                  DisplayMemberPath="Name"
                  SelectedItem="{Binding SelectedDIR1}"
                  Margin="0 5 0 0"/>
    
                <ListBox ItemsSource="{Binding DIR1s}" Margin="0 5 0 0" Height="100">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                             <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
    
                </ListBox>
            </StackPanel>
        </Grid>
    </Window>
    

    #Code Behind

    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Windows;
    
    namespace ColeWPFSample.ComboboxSample
    {
        /// <summary>
        /// Interaction logic for Window2.xaml
        /// </summary>
        public partial class Window2 : Window
        {
            public Window2()
            {
                InitializeComponent();
                this.DataContext = new ViewModel();
            }
        }
    
        public class ViewModel : INotifyPropertyChanged
        {
            public ViewModel()
            {
                this.DIRSs = new List<DIRS>()
                  {
                    new DIRS(){ Name = "Folder1", 
                    Dirs_1 = new List<DIR1>()
                    {
                      new DIR1(){ Name = "EN-Sub11" },
                      new DIR1(){ Name = "EN-Sub12" },
                      new DIR1(){ Name = "EN-Sub13" }
                    }},
                    new DIRS(){ Name = "Folder2",
                    Dirs_1 = new List<DIR1>()
                    {
                      new DIR1(){ Name = "EN-Sub21" },
                      new DIR1(){ Name = "EN-Sub22" },
                      new DIR1(){ Name = "EN-Sub23" }
                    }},
                    new DIRS(){ Name = "Folder3",
                    Dirs_1 = new List<DIR1>()
                    {
                      new DIR1(){ Name = "EN-Sub31" },
                      new DIR1(){ Name = "EN-Sub32" },
                      new DIR1(){ Name = "EN-Sub33" }
                    }}
                  };
    
                //set default country selection:
                this.SelectedDIRS = this.DIRSs[0];
            }
            public IList<DIRS> DIRSs { get; set; }
            public ICollection<DIR1> DIR1s { get; set; }
            private DIRS _selectedDIRS;
            public DIRS SelectedDIRS
            {
                get
                {
                    return _selectedDIRS;
                }
                set
                {
                    _selectedDIRS = value;
                    OnPropertyChanged("SelectedDIRS");
                    this.DIR1s = _selectedDIRS.Dirs_1;
                    OnPropertyChanged("DIR1s");
                }
            }
    
            public DIR1 SelectedDIR1 { get; set; }
    
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(name));
            }
            #endregion
        }
    
        public class DIRS
        {
            public string Name { get; set; }
            public ICollection<DIR1> Dirs_1 { get; set; }
            
        }
    
        public class DIR1
        {
            public string Name { get; set; }
            public DIRS DIRS { get; set; }
            public ICollection<DIR2> Dirs_2 { get; set; }
        }
    
        public class DIR2
        {
            public string Name { get; set; }
            public DIR1 DIR1 { get; set; }
        }
    }
    

    Best regards,

    Zhanglong 


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年6月4日 8:32
  • Hi Zhanglong!

        非常感谢,可能和我说的有点出入,我说的是第一层用下拉列表,后面2层用个使用一个ListBox分组的方式显示子目录。

    目录结构:

    第1层:

    用下拉列表显示"Folder1"和"Folder2"

    "Foldre1"包含: "CN_Sub11", "CN_Sub12","EN_Sub11", "EN_Sub12"

    "Foldre2"包含: "CN_Sub21", "CN_Sub22","EN_Sub21", "EN_Sub22"

    第2层:

    用一个ListBox分2组,第一组是CN,第二组是EN

    当选择下拉列表选择"Folder1"时:

    CN组包含"CN_Sub11", "CN_Sub12"这2个目录

    EN组包含"EN_Sub11", "EN_Sub12"这2个目录

    当选择下拉列表选择"Folder2"时:

    CN组包含"CN_Sub21", "CN_Sub22"这2个目录

    EN组包含"EN_Sub21", "EN_Sub22"这2个目录


    第3层:

    第三层同样使用1个ListBox分组方式显示第2层中的子目录,分为CN和EN2组

    "CN_Sub11"包含"CN_Sub11_11", "CN_Sub11_12"

    "CN_Sub12"包含"CN_Sub12_11", "CN_Sub12_12"

    "EN_Sub11"包含"EN_Sub11_11""EN_Sub11_12"

    "EN_Sub12"包含""EN_Sub12_11""EN_Sub12_12"

    "CN_Sub11"包含"CN_Sub11_11", "CN_Sub11_12""EN_Sub11_11""EN_Sub11_12"

    当选择下拉列表选择"Folder1"时:

    CN组包含"CN_Sub11", "CN_Sub12"这2个目录

    EN组包含"EN_Sub11", "EN_Sub12"这2个目录

    2018年6月5日 10:17
  • Hi,

    试一下这个:

    <Window x:Class="WpfApp2.Window4"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp2"
            mc:Ignorable="d"
            Title="Window4" Height="450" Width="800">
        <Grid>
            <StackPanel Margin="10">
                <ComboBox ItemsSource="{Binding DIRSs}"
                  DisplayMemberPath="Name"
                  SelectedItem="{Binding SelectedDIRS}" >
                </ComboBox>
    
                <ListBox ItemsSource="{Binding DIR1s}" Margin="0 5 0 0" Height="100">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
    
                <ListBox ItemsSource="{Binding DIR2s}" Margin="0 5 0 0" Height="263">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </Window>

    C#:

    namespace WpfApp2
    {
        /// <summary>
        /// Interaction logic for Window4.xaml
        /// </summary>
        public partial class Window4 : Window
        {
            public Window4()
            {
                InitializeComponent();
                this.DataContext = new ViewModel();
            }
        }
    
        public class ViewModel : INotifyPropertyChanged
        {
            public ViewModel()
            {
                this.DIRSs = new List<DIRS>()
                  {
                    new DIRS(){ Name = "Folder1",
                    Dirs_1 = new List<DIR1>()
                    {
                        new DIR1(){ Name = "CN-Sub11" },
                        new DIR1(){ Name = "CN-Sub12" },
                        new DIR1(){ Name = "EN-Sub11" },
                        new DIR1(){ Name = "EN-Sub12" }
                    },
                    Dirs_2=new List<DIR2>
                    {
                        new DIR2(){Name="CN-Sub11-11"},
                        new DIR2(){Name="CN-Sub11-12"},
                        new DIR2(){Name="CN-Sub12-11"},
                        new DIR2(){Name="CN-Sub12-12"},
                        new DIR2(){Name="EN-Sub11-11"},
                        new DIR2(){Name="EN-Sub11-12"},
                        new DIR2(){Name="EN-Sub12-11"},
                        new DIR2(){Name="EN-Sub12-12"}
                    }
                    },
                    new DIRS(){ Name = "Folder2",
                    Dirs_1 = new List<DIR1>()
                    {
                        new DIR1(){ Name = "CN-Sub21" },
                        new DIR1(){ Name = "CN-Sub22" },
                        new DIR1(){ Name = "EN-Sub21" },
                        new DIR1(){ Name = "EN-Sub22" }
                    },
                    Dirs_2=new List<DIR2>
                    {
                        new DIR2(){Name="CN-Sub21-11"},
                        new DIR2(){Name="CN-Sub21-12"},
                        new DIR2(){Name="CN-Sub22-11"},
                        new DIR2(){Name="CN-Sub22-12"},
                        new DIR2(){Name="EN-Sub21-11"},
                        new DIR2(){Name="EN-Sub21-12"},
                        new DIR2(){Name="EN-Sub22-11"},
                        new DIR2(){Name="EN-Sub22-12"}
                    }
                    }
                  };
                
                this.SelectedDIRS = this.DIRSs[0];
            }
            public IList<DIRS> DIRSs { get; set; }
            public ICollection<DIR1> DIR1s { get; set; }
            public ICollection<DIR2> DIR2s { get; set; }
            private DIRS _selectedDIRS;
            public DIRS SelectedDIRS
            {
                get
                {
                    return _selectedDIRS;
                }
                set
                {
                    _selectedDIRS = value;
                    OnPropertyChanged("SelectedDIRS");
                    this.DIR1s = _selectedDIRS.Dirs_1;
                    this.DIR2s = _selectedDIRS.Dirs_2;
                    OnPropertyChanged("DIR1s");
                    OnPropertyChanged("DIR2s");
                }
            }
            
            public DIR1 SelectedDIR1 { get; set; }
    
            #region INotifyPropertyChanged Members
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string name)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null)
                    handler(this, new PropertyChangedEventArgs(name));
            }
            #endregion
        }
    
        public class DIRS
        {
            public string Name { get; set; }
            public ICollection<DIR1> Dirs_1 { get; set; }
            public ICollection<DIR2> Dirs_2 { get; set; }
        }
    
        public class DIR1
        {
            public string Name { get; set; }
            public DIRS DIRS { get; set; }
        }
    
        public class DIR2
        {
            public string Name { get; set; }
            public DIRS DIRS { get; set; }
        }
    
    }

    Regards,

    Frankie


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 oneonce 2018年6月25日 6:10
    2018年6月7日 9:39