WPF 绑定到许多仅在运行时已知的对象

WPF binding to a number of objects only known at runtime

我正在尝试了解 WPF 中绑定的限制(如果有的话)。我了解如何绑定到 XAML 中预定义数量的对象,例如:

<Grid>
   <Grid.RowDefinitions>
       <RowDefinition Height="Auto"/>
       <RowDefinition Height="Auto"/>
   </Grid.RowDefinitions>

   <Grid.ColumnDefinitions>
       <ColumnDefinition/>
       <ColumnDefinition/>
   </Grid.ColumnDefinitions>

   <TextBlock Text="{Binding MyText}" Grid.Row="1" Grid.Column="0"/>
</Grid>

(我使用 TextBlock 只是作为示例,它可以是 Button 或任何其他元素) 现在,假设我需要显示多个 TextBlock 而不是单个 TextBlock,但只有在 运行 时才能知道确切的数字,以及要写入每个 TextBlock 的文本(并且可能我可能想要绑定的其他属性)。这在实践中是可以实现的吗?

要在 WPF 中显示多个项目,您通常会使用基 ItemsControl class 或派生自它的 class 之一。这是继承层次结构图,当您只需要基本功能时,您可以使用 ItemsControl,当您需要更多功能时,可以使用它的派生 class 之一:

ItemsControl 及其 children 提供了一个 ItemsSource 属性,允许您绑定 collection(通常是 ObservableCollection)。但是,对于 user-defined 类型,您还需要提供一个数据模板来告诉控件如何显示内容。

例如,假设您有一个简单的 class,如下所示:

public class Message
{
    public string MyText { get; set; }
}

然后创建它们的列表(在您的情况下,您将在 运行 时间填充列表):

Messages = new List<Message>
{
    new Message { MyText = "SomeText1" },
    new Message { MyText = "SomeText2" },
    new Message { MyText = "SomeText3" },
};

您可以使用以下 xaml:

来显示它们
<ItemsControl ItemsSource="{Binding Messages}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding MyText}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

DataTemplate 旁边,您将添加用于显示类型属性并绑定到它们的控件。

注释

请注意,上面的例子只是简单的实施,只是为了展示如何开始。一旦你变得更高级,你可能需要为你的属性(即 INotifyPropertyChanged)和你的 collection 的 adding/removing 项目实施更改通知,等等