如何根据数据结构集合更新一系列用户控件?
How do I update a series of user controls based on a collection of data structures?
我有一个用户控件 BookViewControl,它只包含一个 StackPanel,我还有一个名为 BookInfoControl 的控件,它在一个 WrapPanel 中包含两个 TextBlock。在 BookViewControl 的代码隐藏中,我有一个数据结构的 Observable 集合(书籍)(名为 BookInfo,其中包含两个字符串属性,一个用于作者,另一个用于书名)。
我想要的是以这样一种方式设置它,当我向可观察集合(书籍)添加或删除一个项目时,BookViewControl 中的堆栈面板将通过添加或删除 BookInfoControl 的实例来更新(其中BookInfoControl 的 txtName 绑定到相应的 BookInfo 的 BookName 属性,而 BookInfoControl 的 txtAuthor 将绑定到相同的 BookInfos AuthorName 属性)。
因此我的问题有两个方面:
1) 如何基于集合动态创建/删除 UserControls。
2) 如何将这些控件添加到另一个 Controls StackPanel。
我知道我可以将 BookInfo 的实例及其属性绑定到 BookInfoControls TextBlocks 的实例(在 XAMl 中使用 Text={Binding SomeDataMember.Path} 或在后面的代码中使用 instanceName.SetBinding(新绑定{ Source = SomeDataMember, Path = new PropertyPath("Path") }); )。但是,这样做不会导致我的 Books 集合的新成员创建 BookInfoControl 的新实例,也不会解决将其添加到 StackPanel 的问题。
我还考虑过加入一些杂物来管理 BookInfoControls 的辅助集合,然后手动同步它,但这看起来太混乱了,我相信 WPF 应该有一种更简单、更简洁的方法。
BookViewControl.xaml
<UserControl x:Class="GenericNamespace.BookViewControl "
... Default Generated Namespace Definitions ...
>
<Grid>
<StackPanel x:Name="pnlCollectionOfBookInfos" />
</Grid>
</UserControl>
BookInfoControl.xaml
<UserControl x:Class="GenericNamespace.BookInfoControl "
... Default Generated Namespace Definitions ...
>
<Grid>
<WrapPanel>
<TextBlock x:Name="txtName"/>
<TextBlock x:Name="txtAuthor"/>
</WrapPanel>
</Grid>
</UserControl>
BookInfo.cs
public class BookInfo
{
public string AuthorName { get; set; } = "";
public string BookName { get; set; } = "";
}
BookViewControl.cs
public partial class BookViewControl: UserControl
{
public ObservableCollection<BookInfo> Books { get; set; } = new ObservableCollection<BookInfo>();
public BookViewControl()
{
this.DataContext = this;
InitializeComponent();
}
}
最后,修改 Books 应该会导致在 BookViewControl 的 StackPanel 中显示或删除 BookInfoControl,其中 BookInfoControls TextBlocks 的文本属性反映了 BookInfo 中公开的属性。
编辑:以下 link 是我根据我在这里得到的答案找到的,并且更深入地了解了这个主题,希望它对下一个提出这个问题的人有用:https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview
欢迎来到 SO!
每当您想使用数据绑定在 WPF 中呈现项目集合时,您必须使用 ItemsControl
或其派生控件之一:
<ItemsControl ItemsSource="{Binding Books}" />
如果你这样做,你会看到每本书都显示为一个字符串,你可以通过为你的书类型声明一个 DataTemplate 来改变它:
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:BookInfo}">
<local:BookInfoControl />
</DataTemplate>
</UserControl.Resources>
我有一个用户控件 BookViewControl,它只包含一个 StackPanel,我还有一个名为 BookInfoControl 的控件,它在一个 WrapPanel 中包含两个 TextBlock。在 BookViewControl 的代码隐藏中,我有一个数据结构的 Observable 集合(书籍)(名为 BookInfo,其中包含两个字符串属性,一个用于作者,另一个用于书名)。
我想要的是以这样一种方式设置它,当我向可观察集合(书籍)添加或删除一个项目时,BookViewControl 中的堆栈面板将通过添加或删除 BookInfoControl 的实例来更新(其中BookInfoControl 的 txtName 绑定到相应的 BookInfo 的 BookName 属性,而 BookInfoControl 的 txtAuthor 将绑定到相同的 BookInfos AuthorName 属性)。
因此我的问题有两个方面: 1) 如何基于集合动态创建/删除 UserControls。 2) 如何将这些控件添加到另一个 Controls StackPanel。
我知道我可以将 BookInfo 的实例及其属性绑定到 BookInfoControls TextBlocks 的实例(在 XAMl 中使用 Text={Binding SomeDataMember.Path} 或在后面的代码中使用 instanceName.SetBinding(新绑定{ Source = SomeDataMember, Path = new PropertyPath("Path") }); )。但是,这样做不会导致我的 Books 集合的新成员创建 BookInfoControl 的新实例,也不会解决将其添加到 StackPanel 的问题。
我还考虑过加入一些杂物来管理 BookInfoControls 的辅助集合,然后手动同步它,但这看起来太混乱了,我相信 WPF 应该有一种更简单、更简洁的方法。
BookViewControl.xaml
<UserControl x:Class="GenericNamespace.BookViewControl "
... Default Generated Namespace Definitions ...
>
<Grid>
<StackPanel x:Name="pnlCollectionOfBookInfos" />
</Grid>
</UserControl>
BookInfoControl.xaml
<UserControl x:Class="GenericNamespace.BookInfoControl "
... Default Generated Namespace Definitions ...
>
<Grid>
<WrapPanel>
<TextBlock x:Name="txtName"/>
<TextBlock x:Name="txtAuthor"/>
</WrapPanel>
</Grid>
</UserControl>
BookInfo.cs
public class BookInfo
{
public string AuthorName { get; set; } = "";
public string BookName { get; set; } = "";
}
BookViewControl.cs
public partial class BookViewControl: UserControl
{
public ObservableCollection<BookInfo> Books { get; set; } = new ObservableCollection<BookInfo>();
public BookViewControl()
{
this.DataContext = this;
InitializeComponent();
}
}
最后,修改 Books 应该会导致在 BookViewControl 的 StackPanel 中显示或删除 BookInfoControl,其中 BookInfoControls TextBlocks 的文本属性反映了 BookInfo 中公开的属性。
编辑:以下 link 是我根据我在这里得到的答案找到的,并且更深入地了解了这个主题,希望它对下一个提出这个问题的人有用:https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview
欢迎来到 SO!
每当您想使用数据绑定在 WPF 中呈现项目集合时,您必须使用 ItemsControl
或其派生控件之一:
<ItemsControl ItemsSource="{Binding Books}" />
如果你这样做,你会看到每本书都显示为一个字符串,你可以通过为你的书类型声明一个 DataTemplate 来改变它:
<UserControl.Resources>
<DataTemplate DataType="{x:Type local:BookInfo}">
<local:BookInfoControl />
</DataTemplate>
</UserControl.Resources>