DataTrigger的值设置为静态资源会给出错误 - “在'DataTrigger'正在使用(密封)之后,它无法修改”

问题描述:

我试图在样式上使用数据触发器来更改属性。DataTrigger的值设置为静态资源会给出错误 - “在'DataTrigger'正在使用(密封)之后,它无法修改”

在遵守 “Minimal, Complete and Verifiable Example” 的要求......

要重现,首先建立在Visual Studio中WPF应用程序。

内App.xaml.cs:

using System.ComponentModel; 
using System.Windows; 

namespace Foo{ 
/// <summary> 
/// Interaction logic for App.xaml 
/// </summary> 
public partial class App : Application, INotifyPropertyChanged { 
     private bool _clicked; 
     public bool Clicked { 
      get { return this._clicked; } 
      set { 
       this._clicked = value; 
       this.PropertyChanged?.Invoke(
        this, new PropertyChangedEventArgs("Clicked")); 
      } 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

内MainWindow.xaml:

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:lib="clr-namespace:System;assembly=mscorlib" 
    xmlns:local="clr-namespace:Foo" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    mc:Ignorable="d" x:Class="Foo.MainWindow" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <lib:Boolean x:Key="True">True</lib:Boolean> 
    </Window.Resources> 
    <Grid> 
     <Button x:Name="button" Click="button_Click"> 
      <Viewbox> 
       <TextBlock Text="Unclicked"> 
        <TextBlock.Style> 
         <Style TargetType="{x:Type TextBlock}"> 
          <Style.Triggers> 
           <DataTrigger 
             Binding="{Binding 
              Clicked, 
              Source={x:Static Application.Current}}" 
              Value="{StaticResource True}"> 
            <Setter Property="Text" Value="Clicked" /> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </TextBlock.Style> 
       </TextBlock> 
      </Viewbox> 
     </Button> 
    </Grid> 
</Window> 

的MainWindow.xaml.cs内 -

using System.Windows; 

namespace Foo{ 
/// <summary> 
/// Interaction logic for MainWindow.xaml 
/// </summary> 
public partial class MainWindow : Window { 
     public MainWindow() { 
      InitializeComponent(); 
     } 

     private void button_Click(object sender, RoutedEventArgs e) { 
      (Application.Current as App).Clicked = !(Application.Current as App).Clicked; 
     } 
    } 
} 

作为一个边注意 - 我尝试将数据触发器的值设置为"True",并且这也不起作用(触发器没有t catch,并且文本不会根据将该属性设置为新值而更改)。

那么,为什么数据触发器没有捕获或在这里工作? (要么与静态资源或文字值)?更相关 - 为什么我得到这个错误? “在'DataTrigger'正在使用(密封)之后,它不能被修改”错误?完成我在这里要做的事情的正确方法是什么? (最好还是使用数据触发器而不是转换器,因为我确实需要在两个值之间切换)。

本地值分配给TextBlock的Text属性的优先级高于Setter在DataTrigger中提供的值。详情请参阅Dependency Property Value Precedence

另一个二传手设置初始文本值:

<TextBlock> 
    <TextBlock.Style> 
     <Style TargetType="TextBlock"> 
      <Setter Property="Text" Value="Unclicked"/> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding Clicked, 
             Source={x:Static Application.Current}}" 
          Value="{StaticResource True}"> 
        <Setter Property="Text" Value="Clicked" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </TextBlock.Style> 
</TextBlock> 

你看,当你使用布尔资源的错误消息,只是XAML设计师抱怨。运行时没有错误。

+0

因此,由文字设置的值(与绑定相对)将取代由setter(或数据触发器设置器)设置的值并使其失效,这是导致我的错误的原因? – Will

+0

确切地说,请参阅链接的MSDN文章以获取详细信息。 – Clemens

+0

谢谢。 我现在没有时间测试,但我会明天,如果它有效,我会标记你的答案是正确的。 – Will