【问题标题】:ControlTemplate Binding to Attached DependencyPropertyControlTemplate 绑定到附加的 DependencyProperty
【发布时间】:2016-11-02 13:05:09
【问题描述】:

我正在为ContentControl 创建一个ControlTemplate,它显示一个带边框的TextBox,其背景可以着色。我创建了一个附加属性来保存一个定义是否显示背景的属性。我似乎无法正确使用语法将附加属性绑定到模板中元素的 Visibility 属性。

附加属性是:

public static class AttachedPropertyExtensions
{
    public static readonly DependencyProperty 
        BackgroundVisible = DependencyProperty.RegisterAttached(
            "BackgroundVisible", 
            typeof(Visibility), 
            typeof(AttachedPropertyExtensions), 
            new PropertyMetadata(default(Visibility)));

    public static void SetBackgroundVisible(UIElement element, Visibility value)
    {
        element.SetValue(BackgroundVisible, value);
    }

    public static Visibility GetBackgroundVisible(UIElement element)
    {
        return (Visibility)element.GetValue(BackgroundVisible);
    }
}

ControlTemplate:

<ControlTemplate x:Key="BorderedTextBlock" TargetType="ContentControl">
    <Grid Margin="{StaticResource TextControlMarginThemeThickness}"
          BorderBrush="{StaticResource TextBoxBorderThemeBrush}"
          BorderThickness="{StaticResource TextControlBorderThemeThickness}">
        <Border x:Name="backgroundBorder"
                Background="{TemplateBinding Background}" 
                Visibility="{Binding Path=con:AttachedPropertiesExtensions.BackgroundVisible, RelativeSource={RelativeSource Mode=TemplatedParent}}" />

        <ScrollViewer HorizontalScrollMode="Disabled" 
                      VerticalScrollMode="Enabled" 
                      VerticalScrollBarVisibility="Visible">
            <ContentPresenter Height="80" 
                              TextWrapping="Wrap"
                              Margin="{StaticResource TextControlThemePadding}" />
        </ScrollViewer>

    </Grid>
</ControlTemplate>

这些用于:

<UserControl ...
             xmlns:con="using:Scanners.Tetra.UWPmvvm.Helpers">
...
    <ContentControl x:Name="lblReturnText" 
                    Template="{StaticResource BorderedTextBlock}" 
                    Content="{Binding ReturnText}" 
                    Background="#DDDDDD" 
                    con:AttachedPropertyExtensions.BackgroundVisible="{Binding ReturnText, Converter={StaticResource HasContentConverter}}" />
    <ContentControl x:Name="lblErrorText" 
                    Template="{StaticResource BorderedTextBlock}" 
                    Content="{Binding ErrorText}" 
                    Background="#C03556" 
                    con:AttachedPropertyExtensions.BackgroundVisible="{Binding ErrorText, Converter={StaticResource HasContentConverter}}" />
</UserControl>

HasContentConverter:

class HasContentConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        string val = (string)value;
        string.IsNullOrWhiteSpace(val))
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed
        }
    ...

应用程序运行时(部署在 ARM 移动设备上),输出中显示以下错误

Error: BindingExpression path error: 'con:AttachedPropertiesExtensions' property not found on 'Windows.UI.Xaml.Controls.ContentControl'. BindingExpression: Path='con:AttachedPropertiesExtensions.BackgroundVisible' DataItem='Windows.UI.Xaml.Controls.ContentControl'; target element is 'Windows.UI.Xaml.Controls.Border' (Name='backgroundBorder'); target property is 'Visibility' (type 'Visibility')

当我改变时

Path=con:AttachedPropertiesExtensions.BackgroundVisible

Path=(con:AttachedPropertiesExtensions.BackgroundVisible)

(或任何带括号的内容)在构建整个 ControlTemplate 时出现错误:

The text associated with this error code could not be found.
E_UNKNOWN_ERROR

如何设置绑定到属性?

【问题讨论】:

  • 首先,正确命名静态只读字段:public static readonly DependencyProperty BackgroundVisibleProperty = ....
  • 好的,但是附加的属性似乎在ContentControl 上工作:HasContentConverter 中的断点成功中断,并且从那时起输出中没有任何消息。仅在实际模板的边框上绑定到Visibility时使用

标签: c# xaml uwp


【解决方案1】:

我无法在此处测试 UWP,因为我们仍在 Win7 上,但在 WPF 中,您的附加属性定义很好,包括名称。看来我对那部分有误。我仍然会重命名它只是为了遵循约定,但 WPF 不在乎。也许 UWP 会——我会确定的。

对我来说,测试您的代码时遇到的问题只是绑定路径。它需要在 Path 周围加上括号,因为它是一个附加属性,而且它们的名称很复杂,不符合 C# 属性命名约定:

Visibility="{Binding (con:AttachedPropertyExtensions.BackgroundVisible), RelativeSource={RelativeSource TemplatedParent}}" 

Path 周围的括号告诉它整个字符串表示一个复杂的属性名称,因此它转到 con:AttachedPropertyExtensions.BackgroundVisibleDependencyProperty 定义字段。否则,它认为con:AttachedPropertyExtensions 应该是模板化父级的一个属性,它有一个名为BackgroundVisible 的自己的属性。但这甚至没有意义。即使这不是语法错误:

public Visibility con:AttachedPropertyExtensions{ get; set; }

...这不是您要在这里交流的内容。

如果我将PresentationTraceSources.TraceLevel=High 添加到您原来的Binding,以下是调试跟踪输出失败的部分:

System.Windows.Data 警告:108:BindingExpression (hash=4917414):在级别 0 - 对于 ContentControl.con:AttachedPropertyExtensions 找到访问器

System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“ContentControl”(名称=“”)上找不到“con:AttachedPropertyExtensions”属性。 BindingExpression:Path=con:AttachedPropertyExtensions.BackgroundVisibility; DataItem='ContentControl'(名称='');目标元素是 'Border' (Name='');目标属性是“可见性”(类型“可见性”)

System.Windows.Data 警告:103:BindingExpression (hash=4917414):将级别 1 的项目替换为 {NullDataItem}

【讨论】:

  • 嗯。我曾尝试过,但 Visual Studio 在构建时抛出了 E_UNKNOWN_ERROR 错误。我刚刚再次尝试在午餐时关闭 Visual Studio,这次成功了。我的猜测是 VS 变得困惑(它似乎对 UWP 做了很多)。谢谢
  • @JonathanTwite 自 2008 年左右以来,Visual Studio 更容易与每个版本混淆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
相关资源
最近更新 更多