2013-06-12 6 views
3

У меня есть модель просмотра, содержащая набор Item Attributes, который, в свою очередь, содержит путь к изображению. В коллекции может быть от 0 .. N атрибутов предметов.Создание шаблона для индексированного свойства

Стеклянная панель в моем представлении содержит три идентичных элемента управления изображением. Каждый элемент управление изображения привязано к пути атрибут элемента изображения:

  • управление изображением 1 привязано к пути изображения 1-го атрибута элемента (найденному в ItemAttributes [0] .Image)
  • управления изображением 2 связанно с путь изображения 2-го атрибута элемента (находится в ItemAttributes 1 .Image)
  • изображения управления 3 связанно с путем изображения 3-го атрибута элемента (находится в ItemAttributes [2] .Image)

Если есть более 3-х атрибутов , они игнорируются. Чтобы иметь возможность иметь 0 - 2 атрибута (что означает, что 1 или более элементов управления изображением будут привязаны к нулю), что, в свою очередь, дает ошибку, указанную в this post, я добавил триггер данных следующим образом:

<DataTrigger Binding="{Binding Attribute1}" Value="{x:Null}"> 
    <Setter Property="Source" Value="{x:Null}"/> 
</DataTrigger> 

Кроме того, для того, чтобы предотвратить индекс из связанного вопроса, я расколоть атрибуты элемента в моей модели представления в три свойства (я изначально был возвращающимся String.Empty, но изменил его обнулить работать с триггеры данных):

public string Attribute1 
{ 
    get { return _item.Attributes.Count > 0 ? _item.Attributes[0].Image : null; } 
} 
public string Attribute2 
{ 
    get { return _item.Attributes.Count > 1 ? _item.Attributes[1].Image : null; } 
} 
public string Attribute3 
{ 
    get { return _item.Attributes.Count > 2 ? _item.Attributes[2].Image : null; } 
} 

Таким образом, моя проблема заключается в том, что я хотел бы, чтобы этот триггер данных работал для всех трех атрибутов изображения и соответствующие элементы управления изображением (наряду с некоторыми другими свойствами, такими как ширина, высота, маржа и т. д.). Поэтому я думаю, поставьте его в стиле и ссылайтесь на него как на статический ресурс. Это не будет работать, если у меня есть три разных свойства с разными именами (Attribute1, Attribute2, Attribute3). Так что теперь я застрял делать это таким образом:

<Image> 
    <Image.Style> 
     <Style TargetType="Image"> 
      <Setter Property="Source" Value="{Binding Attribute1}" /> 
      <Setter Property="Width" Value="44" /> 
      <Setter Property="Height" Value="45" /> 
      <Setter Property="Margin" Value="5" /> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Attribute1}" Value="{x:Null}"> 
        <Setter Property="Source" Value="{x:Null}" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Image.Style> 
</Image> 

Это повторяется для двух других элементов управления изображением, за исключением attribute1 замещен attribute2 и Attribute3.

Итак мне было интересно, если есть способ привязать к коллекции, а не, например,

<DataTrigger Binding="{Binding Attributes}" Value="{x:Null}"> 
    <Setter Property="Source" Value="{x:Null}"/> 
</DataTrigger> 

... а затем specifcy индекс Я заинтересован в контроле изображения обязательным, за пределами шаблон (я думаю, как передать параметр в триггер данных).

Любые идеи ... есть ли другой подход, если это невозможно?

+1

Чувак, почему ты усложнять все это так много? Просто используйте 'ItemsControl' привязанный к некоторому' ObservableCollection' и забудьте 'Attribute1, Attribute2, Attribute3 ...' –

+0

@HighCore: Я все еще довольно зеленый в мире WPF, поэтому я не всегда выбираю самый простой или самый правильный способ сделать что-то. –

ответ

7
<ItemsControl ItemsSource="{Binding Attributes}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Image Source={Binding Something} x:Name=Image/> 
      <DataTemplate.Triggers> 
       <DataTrigger Binding={Binding Something} Value={x:Null}> 
        <Setter TargetName=Image Property=Source Value={x:Null}/> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

Набрал это вручную в ответ, а не настоящий XAML. Но вы должны понимать, что я имею в виду.

Edit: Если ваш Attributes это просто строки, используйте "{Binding}" везде, где я поместил "{Binding Something}"

--update (я буду обновлять свой ответ с тем, что я сделал, так как ваш ответ был правильным) -

<ItemsControl ItemsSource="{Binding Attributes}" 
       Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" Margin="5"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel Orientation="Horizontal" 
         HorizontalAlignment="Left" VerticalAlignment="Top" /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <Image x:Name="Image" 
        Source="{Binding}" 
        Width="45" Height="44" Margin="5" /> 
      <DataTemplate.Triggers> 
       <DataTrigger Binding="{Binding}" Value="{x:Null}"> 
        <Setter TargetName="Image" 
          Property="Source" Value="{x:Null}" /> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

И чтобы ограничить его атрибутами первых трех элементов, это то, что у меня было в конструкторе моей модели. Атрибуты это свойство SmartObservableCollection (выборочная ObservableCollection с и метод AddRange и пара других вкусностей) с _attributes каркасного поле:

_attributes = new SmartObservableCollection<string>(); 
var images = from attributes in _item.Attributes 
      select attributes.Image; 

Attributes.AddRange(images.Take(3)); 
+0

Спасибо. Я дам ему выстрел ... Я все еще учусь, так что из-за меня, как правило, отнюдь не совсем что-то понимает. –

+0

+1 yep, не будет компилироваться, поскольку он свободен, но ядро ​​есть. –

+0

Мое обновление в ответе компилируется. Просто отсутствовали некоторые кавычки вокруг привязки источника изображения и некоторые привязки данных. –

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