Настраивать ControlTemplate, не дублируя его? - PullRequest
1 голос
/ 18 ноября 2011

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

К сожалению, я не могу просто использовать этот метод FindChild () Я нашел в StackOverflow, потому что шаблон, который я хочу изменитьпредставляет заголовок столбца.FindChild () не может помочь изменить шаблон, только созданные элементы управления.Поэтому я могу использовать этот метод для поиска и изменения заголовка первого столбца, но другие столбцы не затрагиваются.Я мог бы изменить код, чтобы найти все заголовки, но если я когда-нибудь решу изменить набор столбцов, я ожидаю, что любые новые столбцы будут созданы из исходного шаблона и не будут включать желаемое изменение.

Если то, что я хочу сделать, невозможно, это нормально, я просто хочу, чтобы кто-то сказал мне об этом:)

Ответы [ 3 ]

1 голос
/ 06 декабря 2011

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

Пример кода:

AttachedMargin Присоединенное свойство:

using System.Windows;

namespace MarginProject
{
    public class AttachedProperties
    {
        public static Thickness GetAttchedMargin(DependencyObject obj)
        {
            return (Thickness)obj.GetValue(AttchedMarginProperty);
        }

        public static void SetAttchedMargin(DependencyObject obj, Thickness value)
        {
            obj.SetValue(AttchedMarginProperty, value);
        }

        // Using a DependencyProperty as the backing store for AttchedMargin.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AttchedMarginProperty =
            DependencyProperty.RegisterAttached("AttchedMargin", typeof(Thickness), typeof(AttachedProperties), new UIPropertyMetadata(new Thickness(0)));       
    }
}

XAML:

<Window x:Class="MarginProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:attprops="clr-namespace:MarginProject"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ControlTemplate x:Key="SimpleButton"  TargetType="{x:Type Button}">
            <Grid>
                <Border Name="BackgroundBorder" Background="{TemplateBinding Background}" BorderBrush="Black" BorderThickness="0,0,1,1" CornerRadius="4"  />
                <Border Name="HighlightBorder" BorderBrush="White" BorderThickness="1,1,0,0" CornerRadius="4" />
                <TextBlock  VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Content}" Margin="{Binding Path=(attprops:AttachedProperties.AttchedMargin), RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}" />
            </Grid>
        </ControlTemplate>

        <Style TargetType="{x:Type Button}">
            <Setter Property="Width" Value="100" />
            <Setter Property="Height" Value="30" />
            <Setter Property="Background" Value="LightBlue" />
            <Setter Property="Template" Value="{StaticResource SimpleButton}" />
        </Style>

    </Window.Resources>
    <StackPanel>
        <Button Content="Hello WPF!" attprops:AttachedProperties.AttchedMargin="25,0,0,0" />
        <Button Content="Hello WPF!" />
    </StackPanel>

</Window>
1 голос
/ 19 ноября 2011

Сказать, что что-то не возможно, всегда сложно, так как существует множество способов решения проблемы, и нужно знать все из них.

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

Если только шаблонопределяется в коде (что маловероятно), в результате вы получите ControlTemplate, который не имеет VisualTree, а Template, который является TemplateContent, о котором в документации должно быть сказано следующее:

Этот класс не имеет публичного API в .NET Framework 4.

Как уже упоминалось, вы можете попробоватьизмените это, используя рефлексию, но я бы не советовал делать это вообще, и я не могу дать вам какое-либо указание на это, поскольку я до сих пор не пытался сделать это.

0 голосов
/ 06 декабря 2011

Не уверен, что это все, что вам нужно, но для свойства style вы можете использовать свойство BasedOn при объявлении стиля и использовать стиль шаблона элемента управления.

<Style x:Key="Style1">
  <Setter Property="Control.Background" Value="Yellow"/>
</Style>

<Style x:Key="Style2" BasedOn="{StaticResource Style1}">
  <Setter Property="Control.Foreground" Value="Blue"/>
</Style>
...