【问题标题】:UWP TemplateBinding in ControlTemplate to fixed valueControlTemplate 中的 UWP TemplateBinding 到固定值
【发布时间】:2024-01-15 05:00:01
【问题描述】:

我想将我的 Controltemplate 中的一个属性 (myHeight) 绑定到父级。以下是我到目前为止的代码。

资源字典

<Style TargetType="local2:TestingControl" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local2:TestingControl">
                <Border
                    Height="{TemplateBinding myHeight}"
                    Background="Green"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">
                    <StackPanel>                            
                        <ContentPresenter Content="{TemplateBinding Content}"/>
                    </StackPanel>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

TestingControl.cs

[ContentProperty(Name = "Content")]
public sealed class TestingControl : Control
{
    public TestingControl()
    {
        this.DefaultStyleKey = typeof(TestingControl);
    }

    public static readonly double myHeight = (double)100;

    public object Content
    {
        get { return (string)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(string), typeof(TestingControl), new PropertyMetadata(string.Empty));
}

我要绑定的是 myHeight。我想在 .cs 中有这个,因为我需要对其进行一些操作。这无法完全加载!


我也尝试了以下方法

资源字典

<x:Double x:Key="myHeight">100</x:Double>
<Style TargetType="local2:TestingControl" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local2:TestingControl">
                <Border
                    Height="{ThemeResource myHeight}"
                    Background="Green"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}">

                    <ContentPresenter Content="{TemplateBinding Content}"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

TestingControl.cs

[ContentProperty(Name = "Content")]
public sealed class TestingControl : Control
{
    public TestingControl()
    {
        this.DefaultStyleKey = typeof(TestingControl);

        var x  = (double)Resources["myHeight"];
    }

    public object Content
    {
        get { return (string)GetValue(ContentProperty); }
        set { SetValue(ContentProperty, value); }
    }

    public static readonly DependencyProperty ContentProperty =
        DependencyProperty.Register("Content", typeof(string), typeof(TestingControl), new PropertyMetadata(string.Empty));
}

第二种方法的问题是,在读取.cs代码中的属性时,var x = (double)Resources["myHeight"];我得到一个异常。

将不胜感激任何一个(最好是两者,因为我只是想学习 UWP)的解决方案。

【问题讨论】:

    标签: c# xaml uwp uwp-xaml


    【解决方案1】:

    第一件事是TemplateBinding应该绑定依赖属性,你写的静态字段不能绑定到Height。

    第二件事是 ThemeResource 会找到主题,但你定义了一个静态源。

    <x:Double x:Key="myHeight">100</x:Double>
    <Style TargetType="local2:TestingControl" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local2:TestingControl">
                    <Border
                        Height="{StaticResource myHeight}"
                        Background="Green"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
    
                        <ContentPresenter Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    第三件事是您首先获得资源,但资源在 OnApplyTemplate 之后初始化。

    您应该将获取资源的代码移至 OnApplyTemplate。

        protected override void OnApplyTemplate()
        {
            try
            {
                // find something in TestingControl.Resources
                var x = Resources["myHeight"];
            }
            catch (Exception e)
            {
    
            }
    
            try
            {
                // find something in App.Resources
                var x = App.Current.Resources["myHeight"];
            }
            catch (Exception e)
            {
    
            }
    
            base.OnApplyTemplate();
        }
    

    如果您的资源是用 App.xaml 编写的,您应该使用 App.Current.Resources 来获取资源。

    如果您想获得海关控制中的资源,您应该将资源添加到您的控制中。

        <local:TestingControl>
            <local:TestingControl.Resources>
                <x:Double x:Key="myHeight">100</x:Double>
            </local:TestingControl.Resources>
        </local:TestingControl>
    

    【讨论】:

    • 我假设你的意思是静态资源而不是静态资源。不幸的是,在 OnApplyTemplate() 中访问仍然不起作用
    • 我创建了一个资源字典并将其包含在 app.xaml 文件中。
    • myHeight的访问器在TestingControl类中
    • 如果您的资源是用 App.xaml 编写的,您应该使用 App.Current.Resources 来获取资源
    • 解决问题的好方法。我应该如何将资源声明为 TestingControl 的一部分?据我所知,TestingControl 没有资源部分,因为它是在模板中定义的。我曾尝试访问 但似乎不存在