是否可以使用XAML在父Page上的两个DependencyProperties之间创建绑定?

ikfrs5lh  于 2022-12-07  发布在  其他
关注(0)|答案(2)|浏览(110)

我在WinUI 3桌面应用程序中有一个名为HomePagePageHomePage有两个DependencyPropertiesP1P2。我希望创建一个绑定,该绑定使用P1作为源,使用P2作为目标(假设P1P2是相同的类型)。这可以很容易地在代码中完成,但是,我可以在XAML中创建绑定吗?
下面是绑定的代码:

public sealed partial class HomePage : Page
{
    public HomePage()
    {
        InitializeComponent();

        // Dependency property identifiers are static public fields. This is the identifier of the Target.
        var targetInfo = typeof(HomePage).GetField("P2Property", BindingFlags.Static | BindingFlags.Public);

        if (targetInfo is not null && targetInfo.FieldType == typeof(DependencyProperty))
        {
            Binding bBinding = new() { Path = new PropertyPath("P1"), Source=this, Mode = BindingMode.OneWay };

            // this is a static field (there are no instance versions) and the value is the identifier of the DependencyProperty
            var dp = (DependencyProperty)targetInfo.GetValue(null);

            ClearValue(dp);
            SetBinding(dp, bBinding);       // create the binding
        }
    }

    // P1
    public static readonly DependencyProperty P1Property = DependencyProperty.Register(
        "P1", typeof(object), typeof(HomePage), new PropertyMetadata(null));
    public object P1
    {
        get => (object)GetValue(P1Property);
        set => SetValue(P1Property, value);
    }

    // P2
    public static readonly DependencyProperty P2Property = DependencyProperty.Register(
        "P2", typeof(object), typeof(HomePage), new PropertyMetadata(null));
    public object P2
    {
        get => (object)GetValue(P2Property);
        set => SetValue(P2Property, value);
    }
}

是否可以改为在XAML中创建绑定(bBinding)?
[编辑]感谢您的回答,我已经尝试过了,但问题仍然存在。以下是HomePage的XAML:

<Page
    x:Class="PFSI.Views.HomePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:views="using:PFSI.Views"
    x:Name="homePage">

    <Grid>
        <!-- Blah -->
    </Grid>
</Page>

定义绑定不是问题-以下任何一项都可以:P2="{Binding P1, ElementName=homePage}" ; P2="{Binding RelativeSource={RelativeSource Self}, Path=P1}" ; DataContext被设置为HomeViewModel,但这在这里并不重要。
我尝试使用建议的<views:HomePage ... />,但结果是堆栈溢出,因为编译器在元素和类之间循环。
我认为Style可能会起作用(类似于:

<Setter Property="P2" Value="{Binding RelativeSource={RelativeSource Self}, Path=P1}"/>

),但是WinUI 3 Styles中的Setters不支持绑定(尽管奇怪的是,绑定在VisualStateManagerSetters中工作)。
我确信这在XAML中应该可以工作--也许它只需要等待SetterBinding的支持?

nkoocmlb

nkoocmlb1#

这种绑定就是所谓的自绑定,用于绑定到标记自身的属性或标记自身属性之间的绑定。

1 -自绑定

通过在Path属性中指定标记的属性,使用RelativeSourceMode.Self访问标记的属性

<local:HomePage P2="{Binding RelativeSource={RelativeSource Self}, Path=P1}"/>

几乎与Andrew的回答相似(显式模式规范):

<local:HomePage P2="{Binding RelativeSource={RelativeSource Mode=Self}, Path=P1}"/>

2 -元素名称

如果布局包含多个相同类型(或self)的元素,也可以尝试通过ElementName绑定:

<local:HomePage x:Name="MyHomePage" P2="{Binding ElementName=MyHomePage, Path=P1}"/>

更多

探索更多关于RelativeSourceBinding标记扩展的信息,深入了解它,因为它在你以后的项目中使用起来真的很方便。顺便看看@james.lee detailed answer关于这个主题。

cig3rfwq

cig3rfwq2#

你可以这样做。

主窗口.xaml

<Window
    x:Class="WinUI3AppPageTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="using:WinUI3AppPageTest"
    mc:Ignorable="d">

    <Grid>
        <local:HomePage P2="{Binding RelativeSource={RelativeSource Mode=Self}, Path=P1}"/>
    </Grid>

</Window>

主页.xaml

<Page
    x:Class="WinUI3AppPageTest.HomePage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:WinUI3AppPageTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">

    <StackPanel>
        <TextBox x:Name="TextControl" Text="{x:Bind P1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="{x:Bind P2, Mode=OneWay}" />
    </StackPanel>
</Page>

主页.xaml.cs

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Threading.Tasks;
using Windows.ApplicationModel.DataTransfer;

namespace WinUI3AppPageTest;

public sealed partial class HomePage : Page
{
    public static readonly DependencyProperty P1Property =
        DependencyProperty.Register(
            nameof(P1),
            typeof(string),
            typeof(HomePage),
            new PropertyMetadata(default));

    public static readonly DependencyProperty P2Property =
        DependencyProperty.Register(
            nameof(P2),
            typeof(string),
            typeof(HomePage),
            new PropertyMetadata(default));

    public HomePage()
    {
        this.InitializeComponent();
    }

    public string P1
    {
        get => (string)GetValue(P1Property);
        set => SetValue(P1Property, value);
    }

    public string P2
    {
        get => (string)GetValue(P2Property);
        set => SetValue(P2Property, value);
    }
}

相关问题