条件绑定属性无法正常工作?

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的设置,当鼠标不再悬停在所选项上时,应该重新显示所选项。然而,这段代码会抛出一个InvalidOperationException异常,并显示“必须为'Property'属性提供非空值。”如果移除使用“Binding”属性的条件,则不会引发异常。根据MSDN文档,必须设置Property或Binding属性之一。上述代码的功能表现得像没有设置Binding属性。实际上,在我所有的测试案例中,无论Binding属性设置为什么,都会引发异常。有什么想法吗?
2个回答

52

有时候你必须承认犯了一个低级错误。但是为了防止其他人也遭到同样的命运,我会分享我的领悟。

首先,如果我仔细阅读了全部文档,我就会知道使用条件的“Binding”属性需要包含在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>

现在这个例子可以工作了,但是由于所选项目已折叠,触发条件会不断切换,导致所选项目在视图中闪烁。虽然有道理,但这显然不是我想要的结果。

总之,希望这能帮助其他人避免犯同样的低级错误!


2
+1 因为承认错误并提供解决方案。其他人也可能会遇到这个问题。漏掉“Data”这个词非常容易忽略。 - Anderson Imes
3
比起寻找并阅读文档,您带领我更快地找到了解决方案。错误信息应该直接说明问题,而不是依赖文档。+1 - jpierson
1
刚刚也犯了同样的错误。你的帖子可能为我节省了一个小时。 - Cameron Peters

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>

我想称呼这另一个不遵循任何约定的 WPF 迷思!? - mkb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接