简体   繁体   English

为索引属性创建模板

[英]Creating template for indexed property

I have a view model that contains a collection of Item Attributes , which in turn each contain a path to an image. 我有一个视图模型,其中包含Item Attributes的集合,每个Item Attributes包含一个图像的路径。 There may be anywhere from 0 .. N item attributes in the collection. 集合中可能有0 .. N项属性。

A stackpanel in my view contains three identical image controls. 我视图中的stackpanel包含三个相同的图像控件。 Each image control is bound to the path of an item attribute image: 每个图像控件都绑定到项目属性图像的路径:

  • image control 1 is bound to 1st item attribute's image path (found in ItemAttributes[0].Image) 图像控件1绑定到第1项属性的图像路径(在ItemAttributes [0] .Image中找到)
  • image control 2 is bound to 2nd item attribute's image path (found in ItemAttributes 1 .Image) 图像控件2绑定到第二项属性的图像路径(在ItemAttributes 1 .Image中找到)
  • image control 3 is bound to 3rd item attribute's image path (found in ItemAttributes[2].Image) 图像控件3绑定到第3项属性的图像路径(在ItemAttributes [2] .Image中找到)

If there are more than 3 attributes, they are ignored. 如果有超过3个属性,则忽略它们。 In order to deal with the possibility of having 0 - 2 attributes (which means 1 or more of the image controls will be bound to null), which in turn gives the error stated in this post , I have added a data trigger like so: 为了处理与具有0的可能性- 2个属性(这意味着该图像控制的1个或多个将被绑定到空),这反过来又使在规定错误此篇 ,我已经添加了一个数据触发器,如下所示:

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

Also, in order to prevent an index out of bound issue, I have split the item attributes in my view model into three properties (i was initially returning String.Empty, but changed it to null to work with the data trigger): 另外,为了防止索引超出绑定问题,我将视图模型中的项属性拆分为三个属性(我最初返回String.Empty,但将其更改为null以使用数据触发器):

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; }
}

So my problem is that I would like to have this data trigger work for all three image attributes and the corresponding image controls (along with some other properties like width, height, margin etc.). 所以我的问题是我希望这个数据触发器适用于所有三个图像属性和相应的图像控件(以及一些其他属性,如宽度,高度,边距等)。 So I think, put it in a style and reference it as a static resource. 所以我认为,把它放在一个样式中并将其作为静态资源引用。 This won't work when I have three different properties with different names (Attribute1, Attribute2, Attribute3). 当我有三个具有不同名称的属性(Attribute1,Attribute2,Attribute3)时,这将不起作用。 So now I am stuck doing it this way: 所以现在我被困在这样做:

<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>

This is repeated for the other two image controls, except the Attribute1 is substituted with Attribute2 and Attribute3. 对于其他两个图像控件重复此操作,但Attribute1替换为Attribute2和Attribute3。

So then I was wondering if there is a way to bind to a collection instead, such as 所以我想知道是否有办法绑定到集合,例如

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

... and then specifcy the index I'm interested in the image control binding, outside of the template (i guess like passing a parameter to the data trigger). ...然后指定我对模板外部的图像控件绑定感兴趣的索引(我想将参数传递给数据触发器)。

Any ideas... is there another approach if this isn't possible? 任何想法......如果不可能,还有另一种方法吗?

<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>

Typed this manually in the answer, not real XAML. 在答案中手动输入,而不是真正的XAML。 But you should be able to understand what I mean. 但你应该能够理解我的意思。

Edit: If your Attributes are just strings, use "{Binding}" wherever I placed "{Binding Something}" 编辑:如果您的Attributes只是字符串,请在我放置"{Binding Something}"任何地方使用"{Binding}" "{Binding Something}"

--UPDATE (I'll update your answer with what I did since your answer was correct)-- --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>

And to limit it to the first three item attributes, this is what I had in my view model's constructor. 并且将它限制为前三个项属性,这就是我在视图模型的构造函数中所拥有的。 Attributes is a SmartObservableCollection property (custom ObservableCollection with and AddRange method and a couple other goodies) with an _attributes backing field: Attributes是一个SmartObservableCollection属性(自定义ObservableCollection with和AddRange方法以及其他一些好东西),带有_attributes支持字段:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM