Изменение шаблона ControlTemplate из кода позади - PullRequest
1 голос
/ 29 ноября 2011

Приложение:

Здравствуйте, я динамически добавляю пользовательские элементы управления в приложение WPF.Элемент управления представляет собой пользовательский слайдер.Я создал ControlTemplate в файле XAML, который я хочу использовать в качестве шаблона для этих динамически создаваемых элементов управления.В настоящее время я применяю шаблон с помощью:

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

В настоящее время это работает нормально (т.е. компилирует, запускает и применяет шаблон).

Шаблон выглядит следующим образом: (Извините за стенутекста)

<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, заключается в том, что он проще, чище и проще в обслуживании / чтении.

Что я хочу:

Я хотел бы внести небольшие изменения в этот элемент управленияшаблон (только цвет заливки объекта Path) в шаблоне ControlTemplate.Если это возможно, я хотел бы получить ссылку на объект ControlTemplate.

Что я пробовал:

Я пытался вызвать FindName ("nameOfPath")в шаблоне он возвращает нулевой объект.

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

Я попытался создать ContentTemlpate, используя множество экземпляров FrameworkElementFactory и построив таким образом ControlTemplate, это не удалось (объект ControlTemplate довольно сложный и имеет многодочерние элементы).

Ответы [ 2 ]

2 голосов
/ 30 ноября 2011

Я бы настоятельно не рекомендовал бы вмешиваться в шаблоны (или, точнее, элементы управления, созданные из шаблонов) во время выполнения таким образом, это плохой дизайн.

Вместо этого вы хотите использовать свойства,Например, связать Path.Fill с Foreground?Если вы считаете, что это недостаточно семантически, вам лучше унаследовать от Slider и создать необходимое свойство, а не возиться с шаблоном во время выполнения.

В вашем случае у вас есть вложенные шаблоны, поэтомупереслать TemplateBinding или сделать что-то с привязкой RelativeSource, решать только вам.например, используя переадресацию:

<!-- ... -->
<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, что также кажется разумным.Теперь вам просто нужно установить Foreground на Slider, чтобы установить Fill пути, хорошо, не правда ли?


В качестве отступления: Вы должны сохранить идеюто, что вы хотите, аннотация.

Я хотел бы внести небольшие изменения в этот шаблон управления ...

Это на самом деле не то, что вы хотите, а следствие того, что выдумаю, что нужно, чтобы получить то, что вы хотите.Вы помещаете в скобки то, что действительно хотите: "[изменения] в цвет заливки объекта Path"

1 голос
/ 29 ноября 2011

Вы, вероятно, не хотите изменять свой шаблон в выделенном коде, потому что это изменило бы каждый элемент управления, который использует этот шаблон.

Вместо этого, после того как ваш элемент управления отображен, вы можете перемещаться по его визуальному деревунайти конкретные элементы, которые необходимо изменить, и изменить их.Событие Loaded запускается после обработки всех событий Render, поэтому вы должны иметь возможность настраивать элементы управления в шаблоне элемента управления во время любого события Loaded.

Я написал набор VisualTreeHelpers, который я использую довольно часто, чтобы найти элементы управления в визуальном дереве WPF.Их можно использовать так:

Path path = VisualTreeHelpers.FindChild<Path>(newControl, "nameOfPath");
...