以下代码的问题是:绑定(bind)到 SomeClassProp.SubTextProp
不起作用(源属性未设置为文本框内容),而绑定(bind)到 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="120" Height="23" />
<TextBox Text="{Binding ElementName=wMain, Path=TextProp}" Width="120" Height="23" />
</StackPanel>
</Window>
和代码:
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; }
}
我是否遗漏了一些明显的东西?
请注意,我需要此绑定(bind)才能从目标(文本框)到源(类属性)。
更新:当我将绑定(bind)从 ElementName=wMain
更改为 RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}
- 两个绑定(bind)工作。所以问题特定于 ElementName
绑定(bind)属性。
最佳答案
好的,终于找到问题了!
在将 diag:PresentationTraceSources.TraceLevel=High
添加到绑定(bind) defs 之后(顺便说一句,非常有用的东西,在没有正常的 ol' 逐步调试的情况下),我在输出中看到以下内容:
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();
}
问题的答案 - 为什么它使用 RelativeSource
属性起作用 - 在于输出日志的这些行:
System.Windows.Data Warning: 66 : BindingExpression (hash=28713467): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 65 : BindingExpression (hash=28713467): Resolve source deferred
使用RelativeSource
进行数据上下文初始化需要树上下文,并延迟到构建Window
之后的某个时间点(到那时SomeClassProperty
已经初始化)。
关于c# - RelativeSource 适用于(嵌套的)子属性,而 ElementName 不适用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18419041/