基于viewmodel类型的边框触发器不起作用

时间:2017-10-28 23:04:14

标签: c# wpf mvvm binding datatrigger

我有一个MainView - 它有一个属性“ViewModel” - 当我将这个ViewModel更改为另一个类型时,我设置将窗口上的datacontext更新为特定的viewmodel然后我使用ContentControl和DataTemplate来更改一些内容 - 这一切都有效。

现在我尝试创建一个触发器来根据viewmodel类型更改边框的背景 - 我想出了这个:

<Border Background="#3f3f3f" CornerRadius="10">
    <Border.Style>
        <Style TargetType="Border">
            <Style.Triggers>
                <DataTrigger Binding="{Binding}" Value="{x:Type viewmodels:AllBeadsViewModel}">
                    <Setter Property="Background" Value="White"></Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
    <StackPanel Orientation="Vertical" VerticalAlignment="Center" Margin="10">
        <Image Height="32" Source="/Images/Icons/bookmark-1.png" Margin="0,0,0,5" />
        <TextBlock Text="All Beads" VerticalAlignment="Center" Foreground="White" />
    </StackPanel>
</Border>

我使用WPF Inspector来尝试确保datacontext是正确的(AllBeadsViewModel)并且正确描述了setter - 所有似乎都匹配。我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

您发布的XAML中存在两个问题。

第一个是直接问题,如何根据对象的类型设置触发器。您的<DataTrigger/>元素引用Binding属性中的当前数据上下文,然后引用Value属性中对象的类型。因此,这要求WPF将数据上下文对象本身System.Type的实例进行比较。由于您的数据上下文对象实际上不是类型,因此永远不会触发。

要解决此问题,您需要一种机制来将当前数据上下文对象的类型AllBeadsViewModel类型进行比较。正如WPF的情况一样,有几种不同的选择。但恕我直言最简单的一种是为触发器的绑定编写IValueConverter,只是在绑定值上返回GetType()的结果。

现在,您发布的XAML仍然无法根据触发器更新边框的背景颜色,因为Background元素takes precedence over any setter found in a style<Border/>属性的显式设置。要解决此问题,您需要删除显式属性值赋值,并将其替换为样式本身中的<Setter/>元素:

<Border CornerRadius="10">
    <Border.Style>
        <p:Style TargetType="Border">
            <Setter Property="Background" Value="#3f3f3f"/>
            <!-- etc. -->
        </p:Style>
    </Border.Style>
    <!-- etc. -->
</Border>

(您可以忽略我添加到上面p:元素的<Style/> XML命名空间......就在那里因为XML / XAML的Stack Overflow代码格式化程序被不合格的{{1元素并停止格式化为XML,直到元素关闭。)

有关XAML的第二个方面/问题的讨论,另请参阅WPF Trigger won't set property if set in Element