У меня есть список объектов типа SomeObject, который определяется как:DisplayMemberPath при использовании ItemsPanelTemplate
public struct SomeObject
{
public SomeObject(int id, string imgPath)
{
Id = id;
ImagePath = imgPath;
}
public int Id;
public string ImagePath;
}
Я хочу, чтобы отобразить эти объекты в ListBox, который показывает одно изображение для каждого объекта и упорядочивает их в плитка. The ItemsTemplate - это просто изображение. The ItemsPanelTemplate - это TilePanel.
Когда я использую только строки (пути к изображениям) в качестве элементов списка вместо объектов SombeObject, все работает, и изображения отображаются правильно.
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionMode="Extended"
SelectionChanged="OnItemSelectionChanged"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:VerticalTileBox}},
Path=SomeObjectsCollectionView, UpdateSourceTrigger=PropertyChanged}"
>
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source ="{Binding}"
VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="Uniform" >
</Image>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<controls:VirtualizingTilePanel ChildSize="{Binding
RelativeSource={RelativeSource AncestorType={x:Type controls:VerticalTileBox}},
Path=ItemSize, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
При использовании элементов SomeObject этот код дает мне список плиток, но изображения не отображаются.
Ошибка System.Windows.Data: 40: Ошибка пути BindingExpression: свойство 'ImagePath' не найдено в 'object' '' SomeObject ' (HashCode = 1739718653)'. BindingExpression: Path = ImagePath; DataItem = 'SomeObject' (HashCode = 1739718653); Целевой элемент - «Изображение» (Name = ''); target is 'Source' (type 'ImageSource')
Ожидается, что я не сказал элементу управления, что именно отображать (какое свойство SomeObject). Использование DisplayMemberPath в дополнение к ItemsPanelTemplate не работает, поэтому как установить свойство, которое будет использоваться для отображения на изображении?
Благодарим за помощь!
редактировать: @ nkoniishvt
Это действительно походит на правильный путь, чтобы сделать это, но я не могу заставить его работать правильно. Что я делаю не так?
Я добавил этот DP в UserControl код позади:
public static readonly DependencyProperty ItemsTemplateProperty =
DependencyProperty.Register("ItemsTemplate",
typeof(DataTemplate),
typeof(VerticalTileBox),
new PropertyMetadata(null));
public DataTemplate ItemsTemplate
{
get {return (DataTemplate)GetValue(ItemsTemplateProperty);}
set {SetValue(ItemsTemplateProperty, value);}
}
и изменил XAML как это:
<ListBox
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionMode="Extended"
SelectionChanged="OnItemSelectionChanged"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:VerticalTileBox}},
Path=ItemCollection, UpdateSourceTrigger=PropertyChanged}"
ItemTemplate="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:VerticalTileBox}},
Path=ItemsTemplate, UpdateSourceTrigger=PropertyChanged}"
>
<ItemsPanelTemplate>
<controls:VirtualizingTilePanel ChildSize="{Binding
RelativeSource={RelativeSource AncestorType={x:Type controls:VerticalTileBox}},
Path=ItemSize, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Шаблон данных определяется следующим образом:
<DataTemplate x:Name="SomeImageItemTemplate" DataType="utilities:SomeObject">
<Image Source ="{Binding Path=ImagePath}"
VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="Uniform" />
</DataTemplate>
В общем, на мой взгляд:
<ctrls:VerticalTileBox Source="{Binding ImageListView, UpdateSourceTrigger=PropertyChanged}" ItemsTemplate="{DynamicResource SomeImageItemTemplate}"/>
В результате отображаются плитки, но все они пусты, за исключением имен классов объектов (SomeObject).
ImagePath должно быть публичным свойством вместо поля, то есть 'public string ImagePath {get; задавать; } '.Затем вы должны написать выражение привязки как «Source =» {Binding ImagePath} "'. – Clemens
Это именно то, чего я не хочу делать. Поле списка расположено в usercontrol «ImageTilePanel» и должно быть повторно использовано для других типов объектов. Поэтому я не хочу устанавливать там имя свойства fix. – tabina
@tabina У вас должно быть свойство DataTemplate, предоставленное пользователем вашего UserControl, а не общий DataTemplate. Поэтому он должен либо добавить свой DataTemplate в качестве ресурсов вашего UserControl, либо у вас должен быть DataTemplate DP, а затем привязать ItemTemplate ItemsControl к этому шаблону. Группа не должна говорить, как отображать детей, только там, где и насколько они велики. – nkoniishvt