我在WinUI 3桌面应用程序中有一个名为HomePage
的Page
。HomePage
具有两个DependencyProperties
、P1
和P2
。我想创建一个使用P1
作为源、P2
作为目标的绑定(假设P1
和P2
属于同一类型(。这可以在代码中轻松完成,但是,我可以在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
不支持绑定(尽管奇怪的是,绑定在VisualStateManager
Setters
中工作(。
我相信这应该在XAML中工作——也许它只需要等待Setter
Binding
的支持?
这种绑定被称为自绑定,用于绑定到标签自己的属性或在标签自己的特性之间绑定。
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}"/>
更多
探索更多关于RelativeSource
和Binding
标记扩展的内容,深入了解它,因为它在您的进一步项目中使用起来非常方便。顺便说一句,你可以看看@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);
}
}