3

のコレクションを含むビューモデルがありItem Attributes、それぞれに画像へのパスが含まれています。0 .. Nコレクション内のアイテム属性のどこかにある可能性があります。

私のビューのスタック パネルには、3 つの同一のイメージ コントロールが含まれています。各イメージ コントロールは、アイテム属性イメージのパスにバインドされます。

  • 画像コントロール 1 は、1 番目の項目属性の画像パス (ItemAttributes[0].Image にあります) にバインドされます。
  • 画像コントロール 2 は、2 番目の項目属性の画像パス (ItemAttributes 1 .Image にあります)にバインドされます。
  • 画像コントロール 3 は、3 番目の項目属性の画像パス (ItemAttributes[2].Image にあります) にバインドされます。

3 つ以上の属性がある場合、それらは無視されます。0 ~ 2 個の属性 (1 つ以上のイメージ コントロールが null にバインドされることを意味します) を持つ可能性に対処するために、この投稿に記載されているエラーが発生するため、次のようなデータ トリガーを追加しました。

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

また、インデックスの範囲外の問題を防ぐために、ビュー モデルのアイテム属性を 3 つのプロパティに分割しました (最初は 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; }
}

したがって、私の問題は、このデータトリガーを3つの画像属性すべてと対応する画像コントロール(幅、高さ、マージンなどの他のプロパティとともに)で機能させたいということです。だから、それをスタイルに入れて、静的リソースとして参照すると思います。異なる名前 (Attribute1、Attribute2、Attribute3) を持つ 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 に置き換えられることを除いて、他の 2 つのイメージ コントロールに対して繰り返されます。

それで、代わりにコレクションにバインドする方法があるかどうか疑問に思っていました。

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

...そして、テンプレートの外側で、イメージ コントロール バインディングに関心のあるインデックスを指定します (パラメータをデータ トリガーに渡すようなものだと思います)。

任意のアイデア...これが不可能な場合、別のアプローチはありますか?

4

1 に答える 1

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 ではなく、回答に手動で入力したものです。しかし、あなたは私の言いたいことを理解できるはずです。

編集:あなた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>

そして、最初の 3 つの項目属性に限定するために、これがビュー モデルのコンストラクターに含まれていたものです。Attributes は、_attributes バッキング フィールドを持つ SmartObservableCollection プロパティ (カスタム ObservableCollection と AddRange メソッドおよびその他の機能) です。

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

Attributes.AddRange(images.Take(3));
于 2013-06-12T18:31:21.803 に答える