开发者

Is there a way to edit a control's template based on the default template?

I'm trying to make just a few minor tweaks to the default template of a checkbox. Now I understand how to make a new template from scratch, but this I do not know. I did manage to (I think?) extract the default template via the method here.

And it spat out:

    <ControlTemplate TargetType="CheckBox" 
                     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                     xmlns:s="clr-namespace:System;assembly=mscorlib" 
                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                     xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna">
        <BulletDecorator Background="#00FFFFFF" SnapsToDevicePixels="True">
            <BulletDecorator.Bullet>
                <mwt:BulletChrome Background="{TemplateBinding Panel.Background}" 
                                  BorderBrush="{TemplateBinding Border.BorderBrush}" 
                                  BorderThickness="{TemplateBinding Border.BorderThickness}" 
                                  RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}" 
                                  RenderPressed="{TemplateBinding ButtonBase.IsPressed}" 
                                  IsChecked="{TemplateBinding ToggleButton.IsChecked}" />
            </BulletDecorator.Bullet>
            <ContentPresenter RecognizesAccessKey="True" 
                              Content="{TemplateBinding ContentControl.Content}" 
                              ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" 
                              ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" 
                              Margin="{TemplateBinding Control.Padding}" 
                              HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" 
                              VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" 
                              SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
        </BulletDecorator>
        <ControlTemplate.Triggers>
            <Trigger Property="ContentControl.HasContent">
                <Setter Property="FrameworkElement.FocusVisualStyle">
                    <Setter.Value>
                        <Style TargetType="IFrameworkInputElement">
                            <Style.Resources>
                                <ResourceDictionary />
                            </Style.Resources>
                            <Setter Property="Control.Template">
                                <Setter.Value>
                                    <ControlTemplate>
                                        <Rectangle Stroke="#FF000000" 
                                                   StrokeThickness="1" 
                                                   StrokeDashArray="1 2" 
                                                   Margin="14,0,0,0" 
                                                   SnapsToDevicePixels="True" />
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="Control.Padding">
                    <Setter.Value>
                        <Thickness>2,0,0,0</Thickness>
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <s:Boolean>True</s:Boolean>
                </Trigger.Value>
            </Trigger>
            <Trigger Property="UIElement.IsEnabled">
                <Setter Property="TextElement.Foreground">
                    <Setter.Value>
                        <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <s:Boolean>False</s:Boolean>
                </Trigger.Value>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

Okay, sure, looks just fine I guess. I don't have enough experience to know if that looks like it's right or not. Now, I get two errors:

Assembly 'PresentationFramework.Luna' was not found. Verify that you are not missing an assembly reference. Also, verify that your project and all referenced assemblies have been built.

and

The type 'mwt:BulletChrome' was not found. Verify that you are not missing an assembly referenc开发者_高级运维e and that all referenced assemblies have been built.

Now I'm wondering, how can I resolve these errors so that I can actually start working on the template? Is there a better way of going about this? My boss wants a three-state checkbox with a red square instead of green, and he won't take no for an answer.


To resolve these two errors, add a reference to PresentationFramework.Luna (it's in the GAC so you'll find it in the .NET tab when choosing Add Reference in VS).

However, note that the Luna theme will only be used by default if the windows XP theme is Luna (the default one). If you change the theme in the display settings, your checkbox will keep the Luna theme since you're reusing the Luna template.

There is no other way to edit only a part of an existing template if the said template hasn't been designed as such in the first place.


The only way to modify parts of an existing Template is to completely override (a copy of) it. You can easily do this (and it will compile right away - no need to reference anything manually) with expression Blend (Edit Template->Edit a copy).

There is one thing you have to keep it mind with ControlTemplates:

There is a separate ControlTemplate for each known OS theme (Luna, Aero etc.) so the control will look correct under each OS theme. If you override it, this is not the case anymore and it will always look the same under every theme under every OS. In your case it will always look like Windows XP Luna (because you chose the Luna ControlTemplate as the starting point) even if you run your app on Vista, Win7 or in Battleship-Gray-Theme.

So to a certain degree overriding ControlTemplates is flawed by design. You could of course, proivde a ControlTemplate for each known OS theme yourself but that will not help if new ones come in.


Aren't there complete copies of all of the control templates included with the Windows SDK?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜