20

私はしばらくの間このコードに苦労してきましたが、私の質問に対する完全な答えが見つからないようです。問題を説明するために小さなサンプルを作成しました。

<ListView >
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
        <StackPanel Margin="0,0,20,0" IsItemsHost="True" />
    </ItemsPanelTemplate>
    </ListView.ItemsPanel>
    <ListView.Items>
        <TextBlock>Test1</TextBlock>
        <TextBlock>Test2</TextBlock>
        <TextBlock>Test3</TextBlock>
        <TextBlock>Test4</TextBlock>
        <TextBlock>Test5</TextBlock>
    </ListView.Items>
    <ListView.ItemContainerStyle>
        <Style TargetType="{x:Type ListViewItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListViewItem}">
                    <Grid>
                        <ContentPresenter/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                 <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
                                 <Condition Property="IsSelected" Value="True"/>
                            </MultiTrigger.Conditions>
                            <Setter Property="Visibility" Value="Collapsed"/>
                        </MultiTrigger>
                    </ControlTemplate.Triggers>
                 </ControlTemplate>
             </Setter.Value>
         </Setter>
         </Style>
     </ListView.ItemContainerStyle>
 </ListView>

MultiTrigger 設定によると、マウスが選択された項目の上になくなると、選択された項目が再表示されます。ただし、このコードは、「'Property' には null 以外の値が必要です」というメッセージを含む InvalidOperationException を生成します。「バインディング」属性を使用する条件を削除すると、例外はスローされません。MSDN のドキュメントでは、Property または Binding 属性を設定する必要があると記載されています。上記のコードは、Binding 属性が設定されていないように機能します。実際、私のすべてのテスト ケースでは、Binding 属性が何に設定されているかは問題ではありません。例外は引き続きスローされます。何かご意見は?

4

2 に答える 2

52

これは、それを吸い上げて、骨の折れる間違いを犯したことを認めなければならないときの1つです. しかし、同じ運命から他の不運な魂を救うために、私は私のひらめきを明らかにします.

まず、すべてのドキュメントを読んだ場合、条件の「バインディング」属性を使用している場合は、MultiDataTrigger 要素に含める必要があるという部分を読んだはずです (投稿された例の MutiTrigger 要素ではなく)。 .

次に、これらの変更を行うと、MultiTrigger 要素が次のコードに置き換えられます。

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsMouseOver}" Value="True" />
        <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
    </MultiDataTrigger.Conditions>
    <Setter Property="Visibility" Value="Collapsed"/>
</MultiDataTrigger>

これで例は機能しますが、選択したアイテムが折りたたまれているため、トリガー条件が前後に切り替わり、選択したアイテムが表示されたり表示されなくなったりします。理にかなっていますが、確かに私が意図したものではありません。

とにかく、これが誰かが同じ骨頭の間違いを犯すのを助けることを願っています!

于 2009-08-11T00:42:15.877 に答える
3

非常によく似たメモとして、IsMouseOver をボーダーからメイン データ テンプレート コンテンツとしてプルし、IsSelected を祖先からプルします。興味深いことに、両方の条件に相対パスが必要です。デフォルト パスはローカル データコンテキストになると思います。上記の解決策をありがとう。

壊れたコード

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
                   Value="True" />
        <Condition SourceName="Border"
                   Property="IsMouseOver"
                   Value="True" />
    </MultiDataTrigger.Conditions>
    <Setter TargetName="Border"
            Property="Background"
            Value="{StaticResource OnBrushSelected}" />
</MultiDataTrigger>

作業コード

<MultiDataTrigger>
    <MultiDataTrigger.Conditions>
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}, Path=IsMouseOver}"
                   Value="True" />
        <Condition Binding="{Binding Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}"
                   Value="True" />
    </MultiDataTrigger.Conditions>
    <Setter TargetName="Border"
            Property="Background"
            Value="{StaticResource OnBrushSelected}" />
</MultiDataTrigger>
于 2010-08-02T18:35:06.623 に答える