wpf - Style setter on the attached property

I believe that you are familiar with the setter in wpf, which enables to set properties of the target control so that you can control the visual/content/template of the controls, normally what you will do is directly set the property which is owned by the target control (or properties from the parent of the target control)

 

while the setter can do more than that, it can also be used to set the attached properties,. here is some example which is used to set the control template of the Contorl called "Expander".

 

 

	<Style x:Key="NomuraExpanderStyle" TargetType="{x:Type Expander}">
		<Setter Property="FocusVisualStyle" Value="{DynamicResource NomuraFocusVisualStyle}"/>		
		<Setter Property="Background" Value="Transparent"/>
		<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
		<Setter Property="VerticalContentAlignment" Value="Stretch"/>
		<Setter Property="BorderBrush" Value="Transparent"/>
		<Setter Property="BorderThickness" Value="1"/>
		<Setter Property="Template">
			<Setter.Value>
				<ControlTemplate TargetType="{x:Type Expander}">
					<Border SnapsToDevicePixels="true">
						<DockPanel>
							<ToggleButton x:Name="HeaderSite" FocusVisualStyle="{DynamicResource NomuraFocusVisualStyle}" MinHeight="0" MinWidth="0" Style="{DynamicResource NomuraDownExpanderToggleButtonStyle}" Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}" FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" FontStretch="{TemplateBinding FontStretch}" FontStyle="{TemplateBinding FontStyle}" FontWeight="{TemplateBinding FontWeight}" Foreground="{DynamicResource ForegroundBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" IsChecked="{Binding IsExpanded, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" DockPanel.Dock="Top"/>
							<ContentPresenter x:Name="ExpandSite" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Focusable="false" Visibility="Collapsed" DockPanel.Dock="Bottom"/>
						</DockPanel>
					</Border>
					<ControlTemplate.Triggers>
						<Trigger Property="IsExpanded" Value="true">
							<Setter Property="Visibility" TargetName="ExpandSite" Value="Visible"/>
						</Trigger>
						<Trigger Property="ExpandDirection" Value="Right">
							<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
							<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
							<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource NomuraRightExpanderToggleButtonStyle}"/>
						</Trigger>
						<Trigger Property="ExpandDirection" Value="Up">
							<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
							<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
							<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource NomuraUpExpanderToggleButtonStyle}"/>
						</Trigger>
						<Trigger Property="ExpandDirection" Value="Down">
							<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Bottom"/>
							<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Top"/>
							<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource NomuraDownExpanderToggleButtonStyle}"/>
						</Trigger>
						<Trigger Property="ExpandDirection" Value="Left">
							<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Left"/>
							<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Right"/>
							<Setter Property="Style" TargetName="HeaderSite" Value="{StaticResource NomuraLeftExpanderToggleButtonStyle}"/>
						</Trigger>
					</ControlTemplate.Triggers>
				</ControlTemplate>
			</Setter.Value>
		</Setter>
		<Setter Property="Foreground" Value="{DynamicResource ForegroundBrush}"/>
		<Setter Property="ExpandDirection" Value="Down"/>
	</Style>

 

The code is apparent on a Attached properties. 

 

<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>

 

What about if the attached properties is home-made one, can you do the same as well?

well the answer is Yes, you can, but you have to watch for namespace prefix. . 

 

Now, suppose that I have endow the control of the ability to swtich between themes, and I have created an attache properties to help attached the very important information to the Control which it decorate, the control is called c1:FlexGrid....

 

Now here is my Behavior's code. 

 

public class ThemeKindChangedEventArgs : EventArgs
    {
        public ThemeKind ThemeKind { get; internal set; }
    }

    public delegate void ThemeKindChanged(DependencyObject d, ThemeKindChangedEventArgs e);

    public class ThemeKindBehavior
    {
        public static readonly DependencyProperty ThemeKindProperty =
            DependencyProperty.RegisterAttached("ThemeKind", typeof (ThemeKind), typeof (ThemeKindBehavior), new PropertyMetadata(default(ThemeKind), new PropertyChangedCallback(OnThemeKindChanged)));

        public static void SetThemeKind(UIElement element, ThemeKind value)
        {
            element.SetValue(ThemeKindProperty, value);
        }

        public static ThemeKind GetThemeKind(UIElement element)
        {
            return (ThemeKind)element.GetValue(ThemeKindProperty);
        }

        public static event ThemeKindChanged ThemeKindChanged;

        public static void OnThemeKindChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (null != d)
            {
                var flexGrid = d as C1FlexGrid;
                if (flexGrid != null)
                {

                    var oldTheme = (ThemeKind) e.OldValue;
                    var theme = (ThemeKind) e.NewValue;
                    var fac = flexGrid.CellFactory as FilterRowCellFactoryWrapper;
                    fac = new FilterRowCellFactoryWrapper(theme);
                    flexGrid.CellFactory = fac;
                    if (oldTheme != theme)
                    {
                        ThemeKindChanged themeChanged = ThemeKindChanged;
                        if (themeChanged != null)
                        {
                            themeChanged(d, new ThemeKindChangedEventArgs() { ThemeKind = theme });
                        }
                    }
                }
            }

        }
    }

 

To use that, I can use the following. 

<dataitemtheme:ThemeKind x:Key="ThemeKind">Unity</dataitemtheme:ThemeKind>

    <Style  TargetType="c1:C1FlexGrid"
            x:Key="RPMC1FlexGrid"
            >
        <Setter Property="ColumnHeaderBackground" Value="{StaticResource C1FlexGridColumnHeaderBackground}" />
        <Setter Property="ColumnHeaderSelectedBackground" Value="{StaticResource C1FlexGridColumnHeaderSelectedBackground}" />
        <Setter Property="GridLinesBrush">
            <Setter.Value>
                <SolidColorBrush Color="#FFC6D7ED" />
            </Setter.Value>
        </Setter>
        <Setter Property="GroupRowBackground">
            <Setter.Value>
                <SolidColorBrush Color="#FFC6D7ED" />
            </Setter.Value>
        </Setter>
		
		
		<!-- here is where you will do the changes -->
		
		<Setter Property="local:ThemeKindBehavior.ThemeKind" Value="{DynamicResource ThemeKind}" />
    </Style>


 So the key here is the use of namespace prefixed names in the "Property" field of Setter object. 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值