У меня есть пользовательский элемент управления BookViewControl, который содержит только StackPanel, у меня также есть элемент управления с именем BookInfoControl, который содержит два TextBlocks в WrapPanel. В Codebehind для BookViewControl у меня есть коллекция Observable (Книги) структуры данных (с именем BookInfo, которая содержит два строковых свойства, одно для автора и другое для имени книги).
Я хочу настроить его таким образом, чтобы при добавлении или удалении элемента в наблюдаемую коллекцию (Книги) панель стека в BookViewControl обновлялась путем добавления или удаления экземпляра BookInfoControl (где txtName of BookInfoControl привязывается к соответствующему свойству BookIname BookInfo, а txtAuthor для BookInfoControl будет привязан к тому же свойству BookInfos AuthorName).
Таким образом, моя проблема двоякая:
1) Как мне динамически создавать / удалять UserControls на основе коллекции.
2) Как мне добавить эти элементы управления в другой StackPanel элементов управления.
Я знаю, что могу связать экземпляр BookInfo и его свойства с экземпляром BookInfoControls TextBlocks (либо в XAMl с Text = {Binding SomeDataMember.Path}, либо в коде с помощью instanceName.SetBinding (new binding {Source =) SomeDataMember, Path = new PropertyPath ("Path")});). Однако это не заставит новых членов моей коллекции Books создавать новый экземпляр BookInfoControl и не решит проблему добавления его в StackPanel.
Я также подумал о том, чтобы добавить kludge для управления вторичной коллекцией 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 должно привести к тому, что BookInfoControl будет отображаться или удаляться в StackPanel BookViewControl, где текстовые свойства BookInfoControls TextBlocks отражают свойства, представленные в BookInfo.
Редактировать: Следующая ссылка - это то, что я нашел после ответа, который я получил здесь, и он углубляется в эту тему, надеюсь, он будет полезен следующему человеку, который задаст этот вопрос: https://docs.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview