2015-08-28 4 views
0

У меня есть список объектов типа 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).

+1

ImagePath должно быть публичным свойством вместо поля, то есть 'public string ImagePath {get; задавать; } '.Затем вы должны написать выражение привязки как «Source =» {Binding ImagePath} "'. – Clemens

+0

Это именно то, чего я не хочу делать. Поле списка расположено в usercontrol «ImageTilePanel» и должно быть повторно использовано для других типов объектов. Поэтому я не хочу устанавливать там имя свойства fix. – tabina

+0

@tabina У вас должно быть свойство DataTemplate, предоставленное пользователем вашего UserControl, а не общий DataTemplate. Поэтому он должен либо добавить свой DataTemplate в качестве ресурсов вашего UserControl, либо у вас должен быть DataTemplate DP, а затем привязать ItemTemplate ItemsControl к этому шаблону. Группа не должна говорить, как отображать детей, только там, где и насколько они велики. – nkoniishvt

ответ

1

У вас не может быть общий DataTemplate, если данные, которые вы поставили как ItemSource вашего ListBox, неизвестны, и ваш UserControl должен оставаться общим.

Вы должны позволить потребителю вашего UserControl предоставить DataTemplate вместо этого, либо в UserControl.Resources, либо в DataTemplate DP вам необходимо создать и привязать к ItemTemplate ListBox.

Панели не должны указывать, как отображаются дети, только там, где и насколько они велики.

+0

Я попытался использовать datatemplate в DP, но он все еще не работает. (Отредактировано мое оригинальное сообщение). – tabina

+0

Ошибка в окне вывода? Я нахожусь на своем телефоне, поэтому я не могу проверить ваш код, но ничего не получается – nkoniishvt

+0

Почему ваш datatemplate передан как динамический ресурс? Попробуйте с staticresource – nkoniishvt

Смежные вопросы