【问题标题】:Dependency Property Not Updating?依赖属性不更新?
【发布时间】:2010-10-19 07:10:50
【问题描述】:

我不知道我是否正确使用了依赖属性,但我的视图似乎永远不会更新。我有一个样式触发器来更改元素的样式。似乎代码运行了,但视图没有更新。这是我第一次使用依赖属性,我可能用错了

C#

public bool CanSave
{
    get { return (bool)GetValue(CanSaveProperty); }
    set { SetValue(CanSaveProperty, value); }
}

public static readonly DependencyProperty CanSaveProperty =
    DependencyProperty.Register("CanSave", typeof(bool), typeof(EditorTabViewModel), new PropertyMetadata(false));

public string Content
{
    get { return _content; }
    set
    {
        if ((bool)GetValue(CanSaveProperty) == false)
        {
            SetValue(CanSaveProperty, true);
            RaisePropertyChanged("CanSave");
        } 
        _content = value;
    }
}

XAML

<TabControl.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal">
            <StackPanel.Resources>
                <Style x:Key="CanSaveIndicatorHeader">
                    <Style.Triggers>
                        <Trigger Property="vm:EditorTabViewModel.CanSave" Value="true">
                            <Setter Property="TextBlock.FontWeight" Value="Bold" />
                        </Trigger>
                        <Trigger Property="vm:EditorTabViewModel.CanSave" Value="false">
                            <Setter Property="TextBlock.Foreground" Value="Red" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </StackPanel.Resources>
            <TextBlock Text="{Binding TabTitle}" Padding="0,0,10,0" Style="{StaticResource CanSaveIndicatorHeader}" />
            <Button Content="X" Command="{Binding CloseCommand}" FontSize="10" FontWeight="Bold" Padding="3,0">
            </Button>
        </StackPanel>
    </DataTemplate>
</TabControl.ItemTemplate>

TextBlock 总是红色 nv 粗体

更新:在选项卡标题前加上 *

<StackPanel Orientation="Horizontal">
    <TextBlock Text="* " x:Name="TabTitleSaveIndicator" Visibility="Collapsed" />
    <TextBlock Text="{Binding TabTitle}" x:Name="TabTitle" Padding="0,0,10,0" />
    <Button Content="X" Command="{Binding CloseCommand}" FontSize="10" FontWeight="Bold" Padding="3,0">
    </Button>
</StackPanel>
<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding CanSave}" Value="True">
        <Setter TargetName="TabTitle" Property="FontWeight" Value="Bold" />
        <Setter TargetName="TabTitleSaveIndicator" Property="Visibility" Value="Visible" />
    </DataTrigger>
</DataTemplate.Triggers>

【问题讨论】:

    标签: c# wpf mvvm observablecollection


    【解决方案1】:

    TextBlock 没有属性“vm:EditorTabViewModel.CanSave”,因此忽略样式触发器。 改用 DataTriggers:

    public class TabItemModel : INotifyPropertyChanged
    {
        public string TabTitle { get; set; }
    
        private bool canSave;
    
        public bool CanSave
        {
            get { return canSave; }
            set
            {
                canSave = value;
                OnPropertyChanged("CanSave");
            }
        }
    //...
    }
    

    标签项模板:

    <TabControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock x:Name="text" Text="{Binding TabTitle}" Padding="0,0,10,0"/>
                    <Button Content="X" Command="{Binding CloseCommand}" FontSize="10" FontWeight="Bold" Padding="3,0">
                    </Button>
                </StackPanel>
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding CanSave}" Value="true">
                        <Setter TargetName="text" Property="TextBlock.FontWeight" Value="Bold" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding CanSave}" Value="false">
                        <Setter TargetName="text" Property="TextBlock.Foreground" Value="Red" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </TabControl.ItemTemplate>
    

    【讨论】:

      【解决方案2】:

      我可以在你的代码中指出两点 -

      1 您的样式缺少 TargetType -

      TargetType="TextBlock"

      另外,您在触发器中使用了 Property,这对我来说是错误的,您应该像这样使用 DataTrigger

      <DataTrigger Binding="{Binding Path=CanSave}" Value="true"> 
      
      • 如果 CanSave 和 TabTitle 属性都在同一个 VM 中。

      2 你的 Content 属性只需要这个

       public string Content  
          {  
               get { return _content; }  
               set  
               {  
                    if (CanSave == false)  
                    {  
                       CanSave=true;  
                    }   
                    _content = value;  
               }  
           }
      

      【讨论】: