为索引属性创建模板

本文关键字:建模 创建 属性 索引 | 更新日期: 2023-09-27 18:18:09

我有一个视图模型,其中包含一组Item Attributes,而每个又包含图像的路径。集合中可能有 0 .. N 项属性的任何位置。

我的视图中的堆栈面板包含三个相同的图像控件。每个图像控件都绑定到项属性图像的路径:

  • 图像控件 1 绑定到第 1 项属性的图像路径(在项属性[0] 中找到(。图片(
  • 图像控件 2 绑定到第 2 项属性的图像路径(在项属性 1.图像中找到(
  • 图像控件 3 绑定到第 3 项属性的图像路径(可在 ItemAttributes[2] 中找到(。图片(

如果属性超过 3 个,则忽略它们。为了处理具有 0 - 2 个属性的可能性(这意味着 1 个或多个图像控件将绑定到 null(,这反过来又给出了本文中所述的错误,我添加了一个数据触发器,如下所示:

<DataTrigger Binding="{Binding Attribute1}" Value="{x:Null}">
    <Setter Property="Source" Value="{x:Null}"/>
</DataTrigger>
此外,为了

防止索引越界问题,我将视图模型中的项目属性拆分为三个属性(我最初返回 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; }
}

所以我的问题是我希望让此数据触发器适用于所有三个图像属性和相应的图像控件(以及其他一些属性,如宽度、高度、边距等(。所以我认为,把它放在一种风格中,并将其作为静态资源引用。当我有三个具有不同名称的不同属性(属性 1、属性 2、属性 3(时,这将不起作用。所以现在我被困在这样做的时候:

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

。然后指定我对模板之外的图像控件绑定感兴趣的索引(我想就像将参数传递给数据触发器一样(。

任何想法...如果这是不可能的,还有另一种方法吗?

为索引属性创建模板

<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。但你应该能够理解我的意思。

编辑:如果你的Attributes只是字符串,请在我放置"{Binding Something}"的地方使用"{Binding}"

-

-更新(我会用我所做的更新你的答案,因为你的答案是正确的(--

<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 with and AddRange 方法以及其他几个好东西(,具有_attributes支持字段:

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