条件绑定属性不起作用?

时间:2009-08-10 18:26:46

标签: wpf binding conditional-statements

我一直在努力使用这段代码已经有一段时间了,似乎无法找到我的问题的完整答案。我已经创建了一个小样本来说明问题:

<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设置,当鼠标不再位于所选项目上时,应重新显示所选项目。但是,此代码会生成一个InvalidOperationException,并显示消息“必须具有'Property'的非空值。”如果删除使用“绑定”属性的条件,则不会抛出异常。在MSDN文档中,它声明您必须设置Property或Binding属性。未设置上述代码函数,如Binding属性。实际上,在我的所有测试用例中,Binding属性的设置并不重要;仍然抛出异常。有什么想法吗?

2 个答案:

答案 0 :(得分:52)

这是你不得不吮吸并承认自己犯了傻瓜错误的时候之一。然而,为了挽救其他一些不幸的灵魂,我会透露我的顿悟。

首先,如果我已经阅读了所有文档,我会阅读部分说如果你使用条件的“绑定”属性,它需要包含在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>

现在该示例有效但由于所选项目已折叠,触发条件来回切换,导致所选项目闪烁进出视图。有道理,但诚然不是我想要的。

无论如何,希望这有助于某人犯同样的错误!

答案 1 :(得分:3)

在一个非常相似的说明中,将IsMouseOver从边界拉为主数据模板内容,并从祖先中拉出IsSelected。有趣的是,两个条件都必须有一个相对路径,我会假设默认路径是本地datacontext。感谢上述解决方案。

破碎的代码

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