views:

42

answers:

2

I don't know if I am using dependency properties right, but it seems my View never updates. I have a style trigger to change the styles of my elements. It seems the code runs, but the view is not updated. This is my 1st time using a Dependency Property & I maybe using it wrong

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>

The TextBlock is always red nv bold

UPDATE: Prefixing the tab header with *

<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>
+2  A: 

TextBlock doesn't have property "vm:EditorTabViewModel.CanSave", so style triggers are ignored. Use DataTriggers instead:

public class TabItemModel : INotifyPropertyChanged
{
    public string TabTitle { get; set; }

    private bool canSave;

    public bool CanSave
    {
        get { return canSave; }
        set
        {
            canSave = value;
            OnPropertyChanged("CanSave");
        }
    }
//...
}

Tab item template:

<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>
vorrtex
thats great, how will you prefix the `text` `TextBlock` with an "*" too?
jiewmeng
update: I found a possible way of doing this in my update
jiewmeng
A: 

I can point out two things in your code -

1 Your style is missing the TargetType -

TargetType="TextBlock"

also, you are using Property in your trigger which looks wrong to me, you should be using DataTrigger like this

<DataTrigger Binding="{Binding Path=CanSave}" Value="true"> 
  • if both CanSave and TabTitle properties are in same VM.

2 Your Content property needs only this

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