WPF 将列表<列表>绑定到将项控件<object>保存为项的项控件



我想显示一个列表,其中包含每个项目包含多个项目的项目。 我试图用 ItemsControls 来实现这一点,以便顶部的 ItemsControl 绑定到包含多个列表的列表。 顶部的 ItemsControl 的项模板包含一个带有样式的标签,该样式定义标签应包含文本框和 ItemsControl。 文本框应绑定到列表的属性,并且 ItemsControl 应绑定到列表本身。此 ItemsControl 再次具有一个文本块作为项模板,该文本块和可见性属性绑定到较低列表中的项的属性。

顶部的项控件:

<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Styles/AlternativeAdressBoxStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid Margin="10,0,10,10">
<Border BorderBrush="Black"
BorderThickness="1">
<ItemsControl ItemsSource="{Binding AlternativeAdressLabelList}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Label Style="{StaticResource AlternativeAdressBoxStyle}"
DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</Grid>

样式文件:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Styles/LabelRowTextBlockStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="AlternativeAdressBoxStyle" 
TargetType="Label">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Label">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="{Binding Path=.AcountingArea}"/>
<Border Grid.Row="1"
Margin="20"
BorderBrush="Black"
BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
Grid.ColumnSpan="2"
Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"></TextBlock>
<ItemsControl Grid.Column="0"
Grid.Row="1"
HorizontalAlignment="Left"
ItemsSource="{Binding Path=.}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource LabelRowTextBlockStyle}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Border>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>

文本块样式:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="LabelRowTextBlockStyle"
TargetType="TextBlock">
<Setter Property="Margin"
Value="0,5"/>
<Setter Property="Height"
Value="20"/>
<Setter Property="Width"
Value="200"/>
<Setter Property="Text"
Value="{Binding Content}"/>
<Setter Property="Visibility"
Value="{Binding Visibility}"/>
</Style>    
</ResourceDictionary>

项控件绑定到的属性:

public List<AlternativeAdressLetterLabel> AlternativeAdressLabelList
{
get { return this._alternativeAdressLabelList; }
set { this.SetProperty( ref this._alternativeAdressLabelList, value); }
}
The list-class which fundamental inherits from List<LabelRow>
<!-- language: c# -->
public class AlternativeAdressLetterLabel : DbConnectedLabelRowList
{
#region fields
private string _sNumber;
private Dictionary<int, string> _acountingArea;
#endregion
#region properties
public string SNumber
{
get { return this._sNumber; }
set
{
this._sNumber = value;
this.OnPropertyChanged();
}
}
public Dictionary<int, string> AcountingArea
{
get { return this._acountingArea; }
set
{
this._acountingArea = value;
this.OnPropertyChanged();
}
}
#endregion

最后是AlternativeAdressLetterLabel持有的类的属性

public string Content
{
get { return this._content; }
set { SetProperty(ref this._content, value); }
}
public string Visibility
{
get { return this._visibility; }
set { SetProperty(ref this._visibility, value); }
}

提前致谢:)

您应该能够实现所需的内容,而无需修改任何控件模板。

在 UserControl 的资源中,您可以定义 2 个DataTemplate资源,这些资源定义ItemsControl中每个项目的显示方式。例如:

<UserControl.Resources>
<DataTemplate x:Key="LabelRowTemplate" DataType="{x:Type model:LabelRow}">
<TextBlock Margin="0,5" Height="20" Width="200" Text="{Binding Content}" />
</DataTemplate>
<DataTemplate x:Key="AlternativeAddressTemplate" DataType="{x:Type model:AlternativeAddressLetterLabel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.1*" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding AccountingArea}" />
<Border Grid.Row="1" Margin="20" BorderBrush="Black" BorderThickness="1">
<StackPanel>
<TextBlock Text="<Whatever text goes here>" />
<ItemsControl ItemsSource="{Binding}" ItemTemplate="{StaticResource LabelRowTemplate}" />
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</UserControl.Resources>

请注意,第二个DataTemplate引用第一个DataTemplate。第二个DataTemplate定义了您希望如何显示"外部"列表中的项目 -ItemsControl顶部的TextBox。模板由其Key属性称为StaticResource

另请注意,在上面的代码中,它假设了一个名为model的命名空间的声明,指向定义类的位置。

xmlns:model="clr-namespace:MyAwesomeCompany.MyAwesomeApp.Model"

定义这些DataTemplate资源后,可以按如下方式声明"外部"列表ItemsControl

<ItemsControl ItemsSource="{Binding AlternativeAddressLabelList}" ItemTemplate={StaticResource AlternativeAddressTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>

这应该可以让您实现所需的布局。

另外一个注意事项 - 如果动态添加这些列表列表,则这些更改不会自动显示在视图中。如果需要,请查看提供 CollectionChanged 事件的集合,例如ObservableCollection<T>

最新更新