如何绑定到 UWP 中的附加属性? [英] How to bind to attached property in UWP?

查看:18
本文介绍了如何绑定到 UWP 中的附加属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将控件的属性绑定到 XAML 中的附加属性(以便附加属性成为绑定的源),但我不知道该怎么做——VS2015 给了我值不在预期范围内"错误,当我运行应用程序时,出现异常.

I need to bind a property of a control to an attached property in XAML (so that the attached property becomes a source of the binding), and I can't figure out how to do it -- VS2015 gives me "Value does not fall within the expected range" error, and when I run the app, I get an exception.

下面显示的技术在 WPF 中完美运行.

The technique shown below worked perfectly in WPF.

这是演示问题的示例应用.

Here is the sample app demonstrating the problem.

AttachedPropertyTest.cs:

AttachedPropertyTest.cs:

namespace App7
{
    public static class AttachedPropertyTest
    {
        public static readonly DependencyProperty FooProperty = DependencyProperty.RegisterAttached(
            "Foo", typeof(string), typeof(AttachedPropertyTest), new PropertyMetadata("Hello world!"));

        public static void SetFoo(DependencyObject element, string value)
        {
            element.SetValue(FooProperty, value);
        }

        public static string GetFoo(DependencyObject element)
        {
            return (string) element.GetValue(FooProperty);
        }
    }
}

MainPage.xaml:

MainPage.xaml:

<!-- Based on the default MainPage.xaml template from VS2015.
     The only thing added is the TextBlock inside the Grid. -->
<Page x:Class="App7.MainPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="using:App7"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{Binding Path=(local:AttachedPropertyTest.Foo), RelativeSource={RelativeSource Self}}"
                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</Page>

而不是显示Hello world!"(这是 Foo 附加属性的默认值)在上面的 TextBlock 上,我收到了从 InitializeComponent 抛出的 XamlParseException.像往常一样,异常对象不包含任何有用的信息.

Instead of displaying "Hello world!" (which is a default value of the Foo attached property) on the TextBlock above, I get XamlParseException, thrown from InitializeComponent. As usual, the exception object does not contain any useful information.

有趣的是,如果我尝试绑定到任何标准(内置于框架中)附加属性,例如 (Grid.Row),则不会发生这种情况,因此 XAML 解析器似乎只是不让我使用自定义附加属性提供程序,这太荒谬了...

Interestingly enough, this doesn't happen if I try to bind to any standard (built into the framework) attached property like (Grid.Row), so it seems that the XAML parser just doesn't let me use a custom attached property provider, which is ridiculous...

那么正确的做法是什么?

So what is the correct way of doing this?

推荐答案

尝试使用 x:Bind 声明而不是 Binding 声明.

Try using the x:Bind declaration instead of the Binding declaration.

<Grid>
    <TextBlock Text="{x:Bind Path=(local:AttachedPropertyTest.Foo) }"
               HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>

但是,使用 x:Bind 的工作原理是生成代码以支持后面代码中的绑定.

However, using x:Bind works by generating code to support the binding in the code behind.

经过一些试验,生成 XamlTypeInfo.g.cs 文件的工具似乎发生了问题,该文件是对已声明 Xaml 元素的编译查找,不幸的是 InitTypeTables() 中缺少 AttachedPropertyTest 注册方法.

After some experimenting, what appears to be happening in an issue with the tool that generated the XamlTypeInfo.g.cs file which is a compiled look up of declared Xaml elements, and unfortunately the AttachedPropertyTest registration is missing from the InitTypeTables() method.

一个有趣的关于生成 XamlTypeInfo 类的文章 描述了您的问题,提供了一些建议,包括使用自定义 IXamlMetadataProvider

An interesting article on the generation of XamlTypeInfo class describes your issue makes few suggestions including using a custom IXamlMetadataProvider

我发现以下更改也有效:

I have found the following changes will also work:

将 AttachedPropertyTest 类的声明从静态更改并添加 Bindable 属性,这将使其可被生成 XamlTypeInfo 类的工具检测到.

Change the declaration of the AttachedPropertyTest class from static and add the Bindable attribute which will make it detectable by the tool generating the XamlTypeInfo class.

[Bindable]
public class AttachedPropertyTest
{
    public static readonly DependencyProperty FooProperty = 
        DependencyProperty.RegisterAttached(
        "Foo", typeof(string), typeof(AttachedPropertyTest), new PropertyMetadata("Hello world!"));

    public static void SetFoo(DependencyObject element, string value)
    {
        element.SetValue(FooProperty, value);
    }

    public static string GetFoo(DependencyObject element)
    {
        return (string)element.GetValue(FooProperty);
    }
}

然后修改xaml声明以包含RelativeSource

Then modify the xaml declaration to include the RelativeSource

    <TextBlock Text="{Binding Path=(local:AttachedPropertyTest.Foo), RelativeSource={RelativeSource Self}, Mode=OneWay}"
               HorizontalAlignment="Center" VerticalAlignment="Center" 
         />

这篇关于如何绑定到 UWP 中的附加属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆