我可以使用XAML在父页上的两个DependencyProperty之间创建绑定吗



我在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(?

[编辑]谢谢你的回答,我已经试过了,但问题仍然存在。这是主页的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}";或者CCD_ 14应该工作,前提是它们可以应用于元件。CCD_ 15被设置为CCD_。

我尝试使用建议的<views:HomePage ... />,但结果是堆栈溢出,因为编译器从元素循环到类并返回。

我认为Style可能会工作(类似于:

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

)但是WinUI 3Styles中的Setters不支持绑定(尽管奇怪的是,绑定在VisualStateManagerSetters中工作(。

我相信这应该在XAML中工作——也许它只需要等待SetterBinding的支持?

这种绑定被称为自绑定,用于绑定到标签自己的属性或在标签自己的特性之间绑定。

1-自绑定

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

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

几乎类似于Andrew的答案(明确的模式规范(:

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

2-元素名称

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

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

更多

探索更多关于RelativeSourceBinding标记扩展的内容,深入了解它,因为它在您的进一步项目中使用起来非常方便。顺便说一句,你可以看看@james.lee关于这个话题的详细答案。

您可以这样做。

主窗口.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);
}
}

最新更新