Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于viewmodel类型的边框触发器不';行不通_C#_Wpf_Mvvm_Binding_Datatrigger - Fatal编程技术网

C# 基于viewmodel类型的边框触发器不';行不通

C# 基于viewmodel类型的边框触发器不';行不通,c#,wpf,mvvm,binding,datatrigger,C#,Wpf,Mvvm,Binding,Datatrigger,我有一个MainView,它有一个属性“ViewModel”-当我将这个ViewModel更改为不同的类型时,我将窗口上的datacontext设置为特定的ViewModel,然后我使用ContentControl和DataTemplate来更改一些内容-这一切都有效 现在,我尝试创建一个触发器,根据viewmodel类型更改边框的背景-我想到了以下方法: <Border Background="#3f3f3f" CornerRadius="10"> <Border.S

我有一个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检查器来尝试并确保datacontext是正确的(AllBeadViewModel),并且setter被正确地描述了——所有这些看起来都是匹配的。我做错了什么?

您发布的XAML中有两个问题

第一个是直接的问题,如何根据对象的类型设置触发器。您的
元素在
绑定
属性中引用当前数据上下文,然后在
属性中引用对象的类型。因此,这要求WPF将数据上下文对象本身与
System.Type
的实例进行比较。因为您的数据上下文对象实际上不是一个类型,所以它永远不会触发

要解决这个问题,您需要一种机制来比较当前数据上下文对象的类型与
AllBeadsViewModel
类型。与WPF的典型情况一样,有几个不同的选项。但是,最简单的方法之一是为触发器的绑定编写一个
IValueConverter
,它只返回绑定值的
GetType()
结果

现在,您发布的XAML仍然不会基于触发器更新边框的背景颜色,因为
元素中
背景
属性的显式设置。要解决此问题,您需要删除显式属性值赋值,并在样式本身中将其替换为
元素:

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

(您可以忽略我添加到上面
元素中的
p:
XML名称空间……这是因为XML/XAML的堆栈溢出代码格式化程序被不合格的
元素弄糊涂了,并停止格式化为XML,直到元素关闭。)


有关XAML的第二个方面/问题的讨论,请参见。

您发布的XAML中有两个问题

第一个是直接的问题,如何根据对象的类型设置触发器。您的
元素在
绑定
属性中引用当前数据上下文,然后在
属性中引用对象的类型。因此,这要求WPF将数据上下文对象本身与
System.Type
的实例进行比较。因为您的数据上下文对象实际上不是一个类型,所以它永远不会触发

要解决这个问题,您需要一种机制来比较当前数据上下文对象的类型与
AllBeadsViewModel
类型。与WPF的典型情况一样,有几个不同的选项。但是,最简单的方法之一是为触发器的绑定编写一个
IValueConverter
,它只返回绑定值的
GetType()
结果

现在,您发布的XAML仍然不会基于触发器更新边框的背景颜色,因为
元素中
背景
属性的显式设置。要解决此问题,您需要删除显式属性值赋值,并在样式本身中将其替换为
元素:

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

(您可以忽略我添加到上面
元素中的
p:
XML名称空间……这是因为XML/XAML的堆栈溢出代码格式化程序被不合格的
元素弄糊涂了,并停止格式化为XML,直到元素关闭。)


有关XAML的第二个方面/问题的讨论,请参见。

如果不清楚地显示您正在尝试做什么,什么不起作用,以及您到底想要什么,就不可能确切地知道什么是好的答案。但是,在您发布的代码中,您似乎正在将对象本身与
System.Type
的实例进行比较。除非您的对象是
类型
,否则将永远不会成功。相反,您可能希望为绑定编写一个转换器,它调用对象上的
GetType()
(即将对象转换为其类型)。“那么比较就有意义了。”彼得杜尼奥谢谢你的回答。真的很难知道要在这个问题上输入多少信息。我当然可以链接我的全部源代码,但那只会产生太多的噪音。因此,我的Window.DataContext是一个类,一个AllBeadViewModel或EditBeadViewModel-基于它是哪一个,我想要一个边框切换背景色。所以是的,我在检查类型。我明白你的意思。所以我做了一个转换器。首先,我尝试将value.GetType()与{x:Type viewmodels:AllBeadsViewModel}匹配-这不起作用-因此我尝试将value.GetType().Name与“AllBeadsViewModel”匹配-仍然没有效果请记住,元素中的显式值集将覆盖在样式中设置它的任何尝试。除了转换器之外,您还应该从
边框
元素声明中删除
背景=“#3f3f”
,并将
添加到样式中。@PeterDuniho就是这样做的!我没有意识到您不能有这样的初始属性,但您必须添加一个setter。如果你给出一个“答案”,我会接受:)如果你不清楚你想做什么,什么不起作用,以及你到底想要什么,你就不可能确切地知道一个好的答案会是什么