C# C ListBox来自对象列表(以及更深层次的列表)
考虑一个书架,它有书架,每个书架上都有很多书。反过来,每本书都有一些属性,比如标题和作者,也许还有ISBNC# C ListBox来自对象列表(以及更深层次的列表),c#,wpf,arrays,list,listbox,C#,Wpf,Arrays,List,Listbox,考虑一个书架,它有书架,每个书架上都有很多书。反过来,每本书都有一些属性,比如标题和作者,也许还有ISBN namespace mySillyExample { public class BookShelf { public Shelf[] myShelves{get; set;} } public class Shelf { public Book[] booksOnThisShelf{get; set;} } public class Boo
namespace mySillyExample
{
public class BookShelf
{
public Shelf[] myShelves{get; set;}
}
public class Shelf
{
public Book[] booksOnThisShelf{get; set;}
}
public class Book
{
public string Title {get; set;};
public string Author{get; set;};
public string ISBN {get; set;};
}
}
现在我想在XAML中创建一个列表框,使用WPF列出所有标题。现在,我的解决方案如下所示:
<ListBox Height="154" HorizontalAlignment="Left"
ItemsSource="{Binding Path=BookShelf.myShelves}"
Margin="171,475,0,0" VerticalAlignment="Top" Width="333" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=booksOnThisShelf.[0].Title}" />
</DataTemplate>
<ListBox.ItemTemplate>
</ListBox>
我得到了一个包含这些数据的列表框。我认为上述解决方案存在三个问题
DataTemplate标签的设计似乎是为了更改列表框将包含的控件类型,而不是在使用时提供额外的绑定范围
对于每个书架书架,我似乎引用了书籍数组中的第0个零/第一个元素。[0]这似乎是最邪恶的,因为如果我确实得到了我所做的所有书籍的列表,那么这似乎不是正在发生的事情
这似乎适用于2层列表,但3层、4层或42层呢
请记住,我不能直接更改类,它们是在XSD中生成的,尽管潜在的助手类并不一定是不可能的
我对这个问题思考得越多,就越确信它会出现在更多的人身上,尤其是在处理来自复杂XML结构网页的数据时?给我所有的img标签等网址
总之,以下是我想要的:
处理上述问题的最佳方式是什么?
最好在XAML中维护的最优雅/可重用的模型
如何将其抽象为包含对象列表的n层列表对象包含对象列表的对象列表。无限/令人作呕?
使用我的示例,如果您有一个包含多个书架的Room类、一个包含多个房间的Library类和一个包含多个库的City类,该怎么办。
一如既往,提前感谢
注意:我使用了术语列表,代码显示了一个数组,很抱歉混淆了要显示所有标题,您可以创建一个静态类/方法来递归地整理所有标题并返回一个平面列表。在XAML中,您可以使用ObjectDataProvider,将其配置为在类型T上调用静态方法X,以获取可以设置为listbox的ItemsSource值的列表。要显示所有标题,您可以创建一个静态类/方法来递归地整理所有标题并返回一个平面列表。在XAML中,您可以使用ObjectDataProvider,将其配置为在类型T上调用静态方法X,以获取可以设置为listbox的ItemsSource值的列表。我建议查看MVVM模式。您不绑定到模型,但绑定到ViewModels。您的ViewModel将帮助您获得巨大的列表。您可能希望这样做:
//ViewModelBase should be a base class that implements INotifyPropertyChanged
public class MyViewModel : ViewModelBase
{
public readonly IDataProvider _provider;
public MyViewModel(IDataProvider provider)
{
_provider = provider ?? (some default provider);
}
public IList<String> Titles
{
get
{
var q = from shelves in _provider.GetBookShelves()
from books in shelves.booksOnThisShelf
select books.Title;
return q as List<String>;
}
}
}
然后您只需要将MyViewModel设置为DataContext并绑定到标题。当然,您不必输入IDataProvider,您可以输入书架列表,但最好让数据提供商为您获取模型信息。我建议您查看MVVM模式。您不绑定到模型,但绑定到ViewModels。您的ViewModel将帮助您获得巨大的列表。您可能希望这样做:
//ViewModelBase should be a base class that implements INotifyPropertyChanged
public class MyViewModel : ViewModelBase
{
public readonly IDataProvider _provider;
public MyViewModel(IDataProvider provider)
{
_provider = provider ?? (some default provider);
}
public IList<String> Titles
{
get
{
var q = from shelves in _provider.GetBookShelves()
from books in shelves.booksOnThisShelf
select books.Title;
return q as List<String>;
}
}
}
然后您只需要将MyViewModel设置为DataContext并绑定到标题。当然,您不必输入IDataProvider,您可以输入书架列表,但最好让数据提供商为您获取型号信息。您也可以这样做
<ListBox Height="154" HorizontalAlignment="Left"
ItemsSource="{Binding Path=BookShelf.myShelves}"
DisplayMemberPath="Title"
Margin="171,475,0,0" VerticalAlignment="Top" Width="333" >
</ListBox>
你也可以这样做
<ListBox Height="154" HorizontalAlignment="Left"
ItemsSource="{Binding Path=BookShelf.myShelves}"
DisplayMemberPath="Title"
Margin="171,475,0,0" VerticalAlignment="Top" Width="333" >
</ListBox>