从代码后面更改ControlTemplate [英] Altering a ControlTemplate from code behind

查看:89
本文介绍了从代码后面更改ControlTemplate的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

应用程序:

您好,我正在向WPF应用程序动态添加自定义控件.该控件是一个自定义滑块.我已经在XAML文件中创建了一个ControlTemplate,我希望将其用作这些动态创建的控件的模板.我目前正在使用以下模板来应用模板:

Hello, I am dynamically adding custom controls to a WPF application. The control is a custom slider. I have created a ControlTemplate in the XAML file which I want to use as the template for these dynamically created controls. I am currently applying the template by using:

newControl.Template = (ControlTemplate)parent.Resources["nameOfTheControlTemplate"];

这目前可以正常运行(即,编译,运行和应用模板).

This currently works OK (i.e. compiles, runs, and applys the template).

模板看起来像这样:(对不起,您的文本墙)

The template looks like this: ( Sorry for wall of text )

<ControlTemplate x:Key="errorRangeSliderRight" TargetType="{x:Type Slider}">
<Border SnapsToDevicePixels="true" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Track x:Name="PART_Track" Grid.Row="1">
            <Track.Thumb>
                <Thumb x:Name="Thumb" HorizontalContentAlignment="Right" Width="7">
                    <Thumb.Template>
                        <ControlTemplate TargetType="Thumb">
                            <Path x:Name="nameOfPath" Stroke="Black" StrokeThickness="0" Fill="Red">
                                <Path.Data>
                                    <GeometryGroup FillRule="NonZero">
                                        <PathGeometry>
                                            <PathGeometry.Figures>
                                                <PathFigure IsClosed="True" StartPoint="7,150">
                                                    <PathFigure.Segments>
                                                        <PathSegmentCollection>
                                                            <LineSegment Point="5,150" />
                                                            <LineSegment Point="5,0" />
                                                            <LineSegment Point="7,0" />
                                                        </PathSegmentCollection>
                                                    </PathFigure.Segments>
                                                </PathFigure>
                                                <PathFigure IsClosed="True" StartPoint="0,75">
                                                    <PathFigure.Segments>
                                                        <PathSegmentCollection>
                                                            <LineSegment Point="7,70" />
                                                            <LineSegment Point="7,80" />
                                                            <LineSegment Point="0,75" />
                                                        </PathSegmentCollection>
                                                    </PathFigure.Segments>
                                                </PathFigure>
                                            </PathGeometry.Figures>
                                        </PathGeometry>
                                    </GeometryGroup>
                                </Path.Data>
                            </Path>
                        </ControlTemplate>
                    </Thumb.Template>
                </Thumb>
            </Track.Thumb>
        </Track>
    </Grid>
</Border>
</ControlTemplate>

原因:

之所以选择在XAML中定义控件模板,而不是使用FrameworkElementFactory来使用数百万行代码动态创建模板,是因为它更容易,更简洁,更易于维护/读取.

The reason why I chose to define the control template in the XAML rather than dynamically create a template using millions of lines of code using FrameworkElementFactory's is because it is easier, cleaner, and easier to maintain/read.

我想要的东西:

我想对ControlTemplate中的此控件模板(仅Path对象的Fill颜色)进行些微更改.如果可能的话,我想获得对ControlTemplate对象的引用.

I would like to make slight alterations to this control template ( only the Fill color of a Path object ) within the ControlTemplate. If it is possible I would like to get a reference to the ControlTemplate object.

我尝试过的事情:

我尝试在模板上调用FindName("nameOfPath"),它返回一个空对象.

I have tried calling a FindName("nameOfPath") on the Template, it returns a null object.

Object o = newControl.Template.FindName("nameOfPath",newControl);

我尝试使用许多FrameworkElementFactory实例创建ContentTemlpate并以这种方式构建ControlTemplate,但这是不成功的(ControlTemplate对象非常复杂,并且具有许多子元素).

I have tried creating the ContentTemlpate using lots of FrameworkElementFactory instances and building the ControlTemplate that way, this was unsuccessful ( the ControlTemplate object is quite complex and has many child elements).

推荐答案

我会以这种方式劝阻强烈在运行时篡改模板(或从模板实例化的控件),这是不好的设计.

I would strongly discourage tampering with templates (or rather controls instantiated from templates) at runtime in this way, it is bad design.

您要使用的是属性.例如,将Path.Fill绑定到Foreground?如果您认为这在语义上不够合适,那么最好从Slider继承并创建所需的属性,而不是在运行时弄乱模板.

What you want to do instead is using properties. For example bind the Path.Fill to the Foreground? If you think that is not semantically fitting enough you would be better off inheriting from Slider and creating the property you need rather than messing with the template at runtime.

在您的情况下,您有嵌套的模板,因此您必须转发TemplateBinding或使用RelativeSource绑定进行某些操作,这取决于您.例如使用转发:

In your case you have nested templates so you have to forward the TemplateBinding or do something with a RelativeSource binding, it is up to you. e.g. using forwarding:

<!-- ... -->
<Thumb x:Name="Thumb" HorizontalContentAlignment="Right" Width="7"
            Background="{TemplateBinding Foreground}">
        <Thumb.Template>
            <ControlTemplate TargetType="Thumb">
                <Path x:Name="nameOfPath" Stroke="Black" StrokeThickness="0"
                      Fill="{TemplateBinding Background}">

这将Path.Fill绑定到Thumb.Background(实际上是),而Thumb.Background绑定到Slider.Foreground似乎也很合理.现在,您只需要在Slider上设置Foreground来设置路径的Fill,很好,不是吗?

This binds the Path.Fill to the Thumb.Background (which it is) and the Thumb.Background is bound to the Slider.Foreground which seems reasonable as well. Now you just need to set the Foreground on the Slider to set the Fill of the path, nice, is it not?

顺便说一句:您应该保持想要抽象的想法.

As an aside: You should keep the idea of what you want abstract.

我想对该控件模板进行一些改动...

I would like to make slight alterations to this control template ...

实际上,这不是您想要的,而是您认为获得您想要的结果所需要的结果.您将真正想要的东西放在括号中:"[[替代] Path对象的填充颜色"

That is in fact not what you want but a consequence that you think is needed to get you what you want. You put what you really want into parenthesis: "[alterations to] the Fill color of a Path object"

这篇关于从代码后面更改ControlTemplate的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆