调整ControlTemplate而不重复它?

时间:2011-11-18 19:41:34

标签: wpf controltemplate

我想在Infragistics xamDataGrid深处的大型ControlTemplate中更改单个对象的边距(好吧,可能是两个)。是否可以在不创建整个模板副本的情况下执行此操作?

不幸的是我不能只使用我在StackOverflow上找到的FindChild() method,因为我想要更改的模板代表一个列标题。 FindChild()不能帮助修改模板,只能实例化控件。所以我可以使用该方法来查找和修改第一个列标题,但其他列不受影响。我可以修改代码来查找所有标题,但如果我决定修改列集,我希望任何新列都将从原始模板中实例化,并且不包含所需的更改。

如果我想做的事情是不可能的,那没关系,我只想让别人告诉我:)

3 个答案:

答案 0 :(得分:1)

说某些东西可能总是很难,因为有很多方法可以解决问题,而且需要知道所有问题。

嗯,在这种情况下,我会说修改模板可能在理论上可能使用大量反思干预内部组件,其实现不应该依赖,所以在实践中它可能是不可能的。

除非在代码中定义模板(这不太可能),否则最终会得到ControlTemplate,但VisualTree只有TemplateTemplateContent,文档必须说明以下内容:

  

此类在.NET Framework 4中没有公共API。

如上所述,您可以尝试使用反射来修改它,但我不建议这样做,我不能给你任何指示,因为我到目前为止没有尝试这样做。

答案 1 :(得分:1)

如果margin是控件模板之间的唯一区别,那么我想你可以编写一个附加属性来处理这个'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>

答案 2 :(得分:0)

不确定这是否会触及您需要的所有内容,但是,对于style属性,您可以在声明样式时使用BasedOnproperty并使用控件模板的样式。

<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>