Cross-ListBox在嵌套的ListBox WP7应用程序中选择

|| Windows Phone 7应用程序中带有嵌套ListBox的已知“问题”是,对于每个父类别,其各自的子ListBox保留其自己的SelectedItems列表。好吧,我遇到了这种情况,这是预期的行为,但是在捕获父级和子级ListBox选定列表时遇到了问题。 当前功能:  1.清单项目  2.清单项目  3.正在加载父子列表框数据  4.父列表框项目的多选可完美运行  5.子列表框项目的多选有效,但不可访问  6.在UI中可以对多个不同的父项选择Child ListBox项,但是在滚动大列表集时将丢失选择,并且无法访问  7. lstCategory可以直接访问,但是lstSubCategory不能直接访问(可能,我只是不知道如何)  8.我绑定到具有一个复杂对象的ViewModel,该对象将两个ListBoxes表示为两个List对象。 预期功能: 我希望能够同时选择“类别”(父项)和“子类别”(子项)ListBox项,如下所示; (X)表示已选择: 面包(X) 面包(X) 牛角包 Buscuit(X) 甜甜圈 水果 小品(X) 草莓 饮品(X) 水 牛奶(X) 果汁(X) 苏打 零食(X) 薯条 薯条 足迹混合 即使列表很长,我也希望保留选择。因此,我要捕获并使用的是: 面包(X) 面包(X) Buscuit(X) 小品(X) 饮品(X) 牛奶(X) 果汁(X) 零食(X) 由于我在每个项目的对象中都有一个CategoryID,因此可以在捕获时剥离层次结构信息。 为了简洁起见,这是代码的本质:
        <ListBox 
            x:Name=\"lstCategory\"
            SelectionMode=\"Multiple\" 
            ItemsSource=\"{Binding Categories}\" 
            FontSize=\"32\" 
            Margin=\"0,0,0,67\">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <StackPanel Orientation=\"Vertical\">
                            <TextBlock Text=\"{Binding CategoryName}\"
                                        FontSize=\"36\"
                                        TextWrapping=\"Wrap\"
                                        Margin=\"20,0,0,0\"
                                        VerticalAlignment=\"Top\"/>
                            <StackPanel  Orientation=\"Vertical\" Margin=\"60,0,0,0\">
                                <ListBox
                                    x:Name=\"lstSubCategory\"
                                    SelectionMode=\"Multiple\" 
                                    ItemsSource=\"{Binding SubCategories}\">
                                    <ListBox.ItemTemplate>
                                        <DataTemplate>
                                            <TextBlock Text=\"{Binding SubCategoryName}\"
                                                       FontSize=\"28\"
                                                       TextWrapping=\"Wrap\"
                                                       VerticalAlignment=\"Top\"/>
                                        </DataTemplate>
                                    </ListBox.ItemTemplate>
                                </ListBox>
                            </StackPanel>
                        </StackPanel>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
和ViewModel:
    public List<Category> Categories { get; set; }

    public PostCategorySelectVM()
    {
        Categories = new List<Category>()
        {
            new Category() 
            { 
                CategoryID = 0, 
                CategoryName = \"Bread\",
                SubCategories = new List<SubCategory>()
                {
                    new SubCategory() {
                        CategoryID = 001,
                        SubCategoryName = \"Loaf\"
                    },
                    new SubCategory() {
                        CategoryID = 002,
                        SubCategoryName = \"Croissant\"
                    }
                    // ...
                }
                // ...
            }
            // ...
        }
    }
类别类别:
public class Category
{
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
    public List<SubCategory> SubCategories { get; set; }
}
子类别类别:
public class SubCategory
{
    public int CategoryID { get; set; }
    public string SubCategoryName { get; set; }
}
保存按钮单击事件:
    private void btnSave_Click(object sender, RoutedEventArgs e)
    {
        foreach (Category item in lstCategory.SelectedItems)
        {
            catList.Add(item);
        }

        foreach (Category cat in catList)
        {
            scatList = cat.SubCategories;
            foreach (SubCategory scat in scatList)
            {
                // How do I select the \"Selected\" SubCategories?
                // How do I select the lstSubCategory control?
            }
        }
    }
最后说明: 我唯一的线索与依赖属性有关,但是我看到的唯一示例需要FrameworkPresentation.dll,该文件在WP7上不可用。 嵌套的ListBox具有预期的UI功能(大列表除去滚动时的交叉选择) 当“类别”和“子类别”都显示在同一屏幕上时,用户体验会感觉最好。 考虑UI功能,例如目录搜索引擎。您可能想以不同的组合选择常规类别和/或子类别,但是父级不需要孩子,子级不需要父母,但是子级和父级都可以存在(出于特殊性)。     
已邀请:
您可以在数据模板中使用复选框而不是文本框,然后将复选框的IsChecked属性绑定到Category / Subcategory类中的IsSelected属性:
    <ListBox x:Name=\"lstCategory\"
        ItemsSource=\"{Binding Categories}\" 
        FontSize=\"32\" 
        Margin=\"0,0,0,67\">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation=\"Vertical\">
                    <CheckBox Content=\"{Binding CategoryName}\"
                                FontSize=\"36\"
                                IsChecked=\"{Binding IsSelected,Mode=TwoWay}\"
                                Margin=\"20,0,0,0\"
                                VerticalAlignment=\"Top\"/>
                    <ListBox ItemsSource=\"{Binding SubCategories}\" Margin=\"60,0,0,0\">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <CheckBox Content=\"{Binding SubCategoryName}\"
                                            FontSize=\"28\"
                                            IsChecked=\"{Binding IsSelected,Mode=TwoWay}\"
                                            VerticalAlignment=\"Top\"/>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
您还应该使类别/子类别类实现INotifyPropertyChanged,以在设置IsSelected时正确触发通知。 假设这样,您的保存将类似于(这并不准确!)
private void btnSave_Click(object sender, RoutedEventArgs e)
{
    catList.Clear();
    catList.AddRange( lstCategory.Items.OfType<Category>().Where(x=>x.IsSelected));

    scatList.Clear();
    foreach (Category cat in catList)
    {
        scatList.AddRange(cat.SubCategories.Where(x=>x.IsSelected));
    }
}
    

要回复问题请先登录注册