调整 ControlTemplate 而不复制它?

发布于 2024-12-16 17:14:39 字数 421 浏览 0 评论 0原文

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

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

如果我想做的事是不可能的,那没关系,我只是希望有人告诉我:)

I want to change the Margin of a single object (well, maybe two) in a large ControlTemplate that is deep within an Infragistics xamDataGrid. Is it possible to do this without creating a duplicate of the entire template?

Unfortunately I can't just use this FindChild() method I found on StackOverflow because the template I want to change represents a column header. FindChild() can't help modify the template, only the instantiated controls. So I can use that method to find and modify the first column header, but the other columns are not affected. I could modify the code to find all of the headers, but if I ever decide to modify the set of columns, I expect that any new columns would be instantiated from the original template and would not include the desired change.

If what I want to do is impossible, that's okay, I just want someone to tell me so :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终难遇 2024-12-23 17:14:39

说某件事不可能总是很难,因为解决问题的方法有很多种,而且需要了解所有方法。

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

除非模板是在代码中定义的(这不太可能),否则您最终会得到一个没有 VisualTreeTemplate 这是一个TemplateContent,关于文档必须说明 下列的:

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

正如前面提到的,您可以尝试使用反射来修改它,但我根本不建议这样做,而且我无法给您任何指导,因为到目前为止我还没有尝试这样做。

Saying that something is not possible is always hard as there are many ways to approach a problem and one would need to know all of them.

Well, in this case i would say that modifying a template might be possible in theory using a lot of reflection meddling with internal components whose implementation one should not rely on, so in practice it probably is impossible.

Unless the template is defined in code (which is unlikely) you will end up with a ControlTemplate that has no VisualTree but a Template which is a TemplateContent, about which the documentation has to say the following:

This class has no public API in .NET Framework 4.

As mentioned you could try to modify this using reflection but i would not recommend doing so at all and i cannot give you any direction on it as i did not try to do that so far.

樱花细雨 2024-12-23 17:14:39

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

If margin is the only difference between the control templates then I suppose you could write an attached property to deal with this say 'AttachedMargin'. On the control give AttachedMargin a value, and use this value inside your Control Template.

Example code:

AttachedMargin Attached property:

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>
凯凯我们等你回来 2024-12-23 17:14:39

不确定这是否满足您需要的所有内容,但是,对于样式属性,您可以使用 BaseOnproperty 声明样式时使用控件模板的样式。

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

Not sure if this hits everything you need, but, for the style property, you can use the BasedOnproperty when declaring a style and use the style of the control template.

<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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文