1

I have the following style for a Tabitem which contains a close button.

<Style x:Key="StudioTabItem" TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                ...
                <Button Grid.Column="2" 
                        Width="15" 
                        Height="15" 
                        HorizontalAlignment="Center" 
                        VerticalAlignment="Center" 
                        Visibility={Binding}> 
                ...

I would like to make the visibility of the StudioTabItems button optional when I use the actual control. So something like

<TabControl x:Name="tabControl" 
            Style="{StaticResource StudioTabControl}"
            ItemsSource="{Binding Workspaces}" 
            SelectedIndex="{Binding SelectedIndex}"
            TabStripPlacement="Top" >
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem" 
                   BasedOn="{StaticResource StudioTabItem}"
                   IsCloseButtonVisible="False"> <-- How to do this?

See the IsCloseButtonVisible on the last line of the above. I know this is likely to involve DependencyProperties. Is this possible and how can I achieve this?

Thanks for your time.

MoonKnight
  • 23,214
  • 40
  • 145
  • 277

1 Answers1

1

This can be achieved by creating the Attached Property like below and by setting its property in style setter

    public static class TabItemBehaviour
    {
        public static readonly DependencyProperty IsCloseButtonVisibleProperty =
            DependencyProperty.RegisterAttached("IsCloseButtonVisible", typeof(bool), typeof(TabItemBehaviour), new UIPropertyMetadata(true, IsButtonVisiblePropertyChanged));

        public static bool GetIsCloseButtonVisible(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsCloseButtonVisibleProperty);
        }

        public static void SetIsCloseButtonVisible(DependencyObject obj, bool value)
        {
            obj.SetValue(IsCloseButtonVisibleProperty, value);
        }

        public static void IsButtonVisiblePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            TabItem item = o as TabItem;
            if (item != null)
            {
               Button closeButton = item.Template.FindName("CloseButton", item) as Button;
               if ((bool)e.NewValue == true)
               {
                   closeButton.Visibility = Visibility.Visible;
               }
               else
               {
                   closeButton.Visibility = Visibility.Collapsed;
               }
            }
        }
    }

And then TabItem style just set the property:

<Style TargetType="TabItem" 
                   BasedOn="{StaticResource StudioTabItem}"
                   > 
<Setter Property="behaviours:TabItemBehaviour.IsCloseButtonVisible" Value="False"/>

Also you will have to give Button a Name "CloseButton" in your ControlTemplate

Nitin
  • 18,344
  • 2
  • 36
  • 53
  • Thanks very much for your reply. Quick question, why is there no property/accessor for the dependency property? – MoonKnight Sep 22 '13 at 15:43
  • There are get/set method for the attached property.... Also for dependancy property we dont need to define the Property wrapper as WPF framework calls base class GetValue and SetValue while accessing the Dependancy property for binding – Nitin Sep 22 '13 at 15:46
  • I don't quite understand why, when I type `propdp` and I get a different looking template for the DependencyProperty than the one being used here. I am confused as to why you are using `DependencyProperty.RegisterAttached` instead of `DependencyProperty.Register`. Sorry to be a pain! – MoonKnight Sep 22 '13 at 15:50
  • 1
    it is perfectly fine.. this the difference between the Attached and Dependency property... Dependency property needs to be set on the object where it is defined.. e.g Background of Tabitem is a Dependancy property.. while the Attached Property can be set on any Dependancy object even if it is not defining it.. e.g we can set Grid.Row on any control even if it does not define it.. here we needed the Attached property thats why i used RegisterAttached – Nitin Sep 22 '13 at 15:54
  • Thanks, one last thing. are we able to use the property like `` because this does not seem to be possible? Again, sorryfor all the questions... – MoonKnight Sep 22 '13 at 16:02
  • @Killercam: Please see my [answer](http://stackoverflow.com/questions/16963221/behavior-of-dependencyproperty-with-regards-to-multiple-frameworkelement-instanc/16966727#16966727) about difference via `attached` and not attached property, may be help. – Anatoliy Nikolaev Sep 22 '13 at 16:33
  • yes you can use it.. u will have to include the xmlns Behaviours which is defining your StudioTabItemBehaviours – Nitin Sep 22 '13 at 17:00