RelativeSource适用于(嵌套)子属性,而ElementName不 [英] RelativeSource works on (nested) sub-property, while ElementName does not
问题描述
以下代码的问题是:绑定到 SomeClassProp.SubTextProp
不起作用(源属性未设置为文本框内容),而 TextProp
它是。
XAML:
< Window x:Class =TestWPF.MainWindow
xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x =http://schemas.microsoft.com/winfx/2006/xaml
Title =MainWindow
Name =wMain
SizeToContent = WidthAndHeight>
< StackPanel>
< TextBox Text ={Binding ElementName = wMain,Path = SomeClassProp.SubTextProp}Width =120Height =23/>
< TextBox Text ={Binding ElementName = wMain,Path = TextProp}Width =120Height =23/>
< / StackPanel>
< / Window>
代码:
public partial class MainWindow:Window
{
public SomeClass SomeClassProp {get;组; }
public string TextProp {get;组; }
public MainWindow()
{
InitializeComponent();
SomeClassProp = new SomeClass();
}
}
public class SomeClass
{
public string SubTextProp {get;组;
}
我在这里缺少一些明显的东西?
注意,我需要这个绑定从目标(文本框)到源(类属性)工作。
更新:当我更改绑定从 ElementName = wMain
到 RelativeSource = {RelativeSource FindAncestor,AncestorType = {x:Type Window}}
- BOTH绑定工作。所以这个问题是针对 ElementName
binding属性的。
好的,最后我发现了这个问题!
添加 diag:PresentationTraceSources.TraceLevel = High
绑定defs(非常有用的东西btw,没有正常的ol'分步调试),我在输出中看到以下内容:
System.Windows.Data警告:108: BindingExpression(hash = 54116930):在0级 - 对于MainWindow.SomeClassProp找到的访问器RuntimePropertyInfo(SomeClassProp)
System.Windows.Data警告:104:BindingExpression(hash = 54116930):使用MainWindow = 47283970),使用访问器RuntimePropertyInfo(SomeClassProp)
System.Windows.Data警告:101:BindingExpression(hash = 54116930):使用RuntimePropertyInfo(SomeClassProp)的MainWindow(hash = 47283970)的级别0的GetValue:
System.Windows.Data警告:106:BindingExpression(hash = 54116930):级别为1的项目为空 - 无访问者
System.Windows.Data警告:80:BindingExpression(hash = 54116930):TransferValue - 值{DependencyPrope rty.UnsetValue}
System.Windows.Data警告:88:BindingExpression(hash = 54116930):TransferValue - 使用回退/默认值''
System.Windows.Data警告:89:BindingExpression(hash = 54116930):TransferValue - 使用最终值''
问题是按照MainWindow初始化的顺序! / p>
所以当构建绑定时,我的0级属性( SomeClassProp
)尚未初始化,导致绑定完全失败(由于某种原因没有发出正常级别的binging警告)。
长篇短篇小说 SomeClassProp
intitialization之前的 InitializeComponent()
在 MainWindow
构造函数中做了诀窍,绑定开始使用 ElementName
也:
public MainWindow()
{
SomeClassProp = new SomeClass();
InitializeComponent();
}
问题的答案 - 为什么使用 RelativeSource
属性 - 位于输出日志的这些行:
系统.Windows.Data警告:66:BindingExpression(hash = 28713467):RelativeSource(FindAncestor)需要树上下文
System.Windows.Data警告:65:BindingExpression(hash = 28713467):解析源延迟
使用 RelativeSource
的数据上下文初始化需要树上下文,并推迟到在 Window
(当时 SomeClassProperty
已经初始化)之后的某个时间点。
The problem with the code below is: the binding to SomeClassProp.SubTextProp
doesn't work (the source property is not being set to textbox content), while to TextProp
it does.
XAML:
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Name="wMain"
SizeToContent="WidthAndHeight">
<StackPanel>
<TextBox Text="{Binding ElementName=wMain, Path=SomeClassProp.SubTextProp}" Width="120" Height="23" />
<TextBox Text="{Binding ElementName=wMain, Path=TextProp}" Width="120" Height="23" />
</StackPanel>
</Window>
and the code:
public partial class MainWindow : Window
{
public SomeClass SomeClassProp { get; set; }
public string TextProp { get; set; }
public MainWindow()
{
InitializeComponent();
SomeClassProp = new SomeClass();
}
}
public class SomeClass
{
public string SubTextProp { get; set; }
}
Am I missing something obvious here?
Note that I need this binding to work from target (textbox) to source (class property).
UPDATE: When I change the binding from ElementName=wMain
to RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}
- BOTH bindings work. So the problem is specific to ElementName
binding property.
Ok, finally, I found the problem!
After adding diag:PresentationTraceSources.TraceLevel=High
to binding defs (very useful thing btw, in the absence of normal ol' step-by-step debugging), I saw the following in the output:
System.Windows.Data Warning: 108 : BindingExpression (hash=54116930): At level 0 - for MainWindow.SomeClassProp found accessor RuntimePropertyInfo(SomeClassProp) System.Windows.Data Warning: 104 : BindingExpression (hash=54116930): Replace item at level 0 with MainWindow (hash=47283970), using accessor RuntimePropertyInfo(SomeClassProp) System.Windows.Data Warning: 101 : BindingExpression (hash=54116930): GetValue at level 0 from MainWindow (hash=47283970) using RuntimePropertyInfo(SomeClassProp): System.Windows.Data Warning: 106 : BindingExpression (hash=54116930): Item at level 1 is null - no accessor System.Windows.Data Warning: 80 : BindingExpression (hash=54116930): TransferValue - got raw value {DependencyProperty.UnsetValue} System.Windows.Data Warning: 88 : BindingExpression (hash=54116930): TransferValue - using fallback/default value '' System.Windows.Data Warning: 89 : BindingExpression (hash=54116930): TransferValue - using final value ''
The problem was in the order of MainWindow initialization!
So at the moment when the binding was constructed, my level 0 property (SomeClassProp
) was not yet initialized, which resulted in binding failing completely (without issuing a normal-level binging warning for some reason).
Long story short - moving SomeClassProp
intitialization before the InitializeComponent()
in MainWindow
constructor did the trick, binding started to work with ElementName
too:
public MainWindow()
{
SomeClassProp = new SomeClass();
InitializeComponent();
}
The answer to question - why it worked using RelativeSource
property - lies in these lines of the output log:
System.Windows.Data Warning: 66 : BindingExpression (hash=28713467): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 65 : BindingExpression (hash=28713467): Resolve source deferred
Data context initialization with RelativeSource
requires tree context, and is deferred to some point in time after construction of the Window
(by that time SomeClassProperty
was already initialized).
这篇关于RelativeSource适用于(嵌套)子属性,而ElementName不的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!