[英]WPF : Binding only working when using Snoop
我们在 WPF 应用程序中使用自定义弹出窗口。 WPF 本机弹出窗口的问题在于:
我们的自定义弹出窗口与原生 WPF 弹出窗口的不同之处在于,它将弹出窗口的内容放在同一窗口的容器中,而不是放在新窗口中。 并且内容是弹出窗口的逻辑孩子。 所以它解决了DataContext和DP继承的原生弹出问题。
我们的 Popup 像 XAML 中的原生一样工作
<pop:UbiPopup IsOpen="{Binding ElementName=pop_button,Path=IsChecked,Mode=TwoWay}" PlacementTarget="{Binding ElementName=maingrid}" Placement="CenterHorizontal,Top" >
<Border Background="Blue" BorderThickness="0" Margin="5">
<TextBlock Text="{Binding Label}"
</Border>
</pop:UbiPopup>
但是绑定有一个错误。 当在弹出窗口的内容中完成绑定时,绑定将不起作用。 但是,如果我们使用 Snoop ( https://github.com/snoopwpf/snoopwpf ) 并检查对象,则 Binding 会突然起作用。 它使用 datacontext 或 elementname 为每种绑定执行此操作。
在内部,当 snoop 显示对象的 DP 列表时,如果它由于某种原因找到绑定,则将其删除并重新放回。 所以我们想出了这个相当丑陋的 hack 来使绑定工作。 当弹出内容加载完毕后,我们沿着所有的visual child,通过反射获取他们所有的DP,如果有绑定,我们将其移除并重新放回🤮
警告:丑陋的代码
//Binding don't work inside UbiPopup. They work if they are snooped.
//So we simulate Snoop. we check every DP of every visual children of the Popup and we re-set the Binding if one is found.
foreach (var obj in WpfHelper.ChildrenEnumerator(container))
{
var props = obj.GetType().GetFields(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy)
.Where((f) => f.FieldType.Equals(typeof(DependencyProperty)))
.Select((f) => f.GetValue(null) as DependencyProperty);
foreach (var p in props)
{
var bd = BindingOperations.GetBindingBase(obj, p);
if (bd != null)
{
BindingOperations.SetBinding(obj, p, bd);
}
}
}
有谁知道这个问题可能来自哪里以及如何以更清洁的方式解决它
Snoop 不会删除和重新应用绑定。 它所做的是创建新的绑定,绑定到对象/控件的 DependencyProperties,这会导致再次评估您的绑定。
您写道,您正在将内容添加到逻辑树,如果您通过调用 AddLogicalChild 来做到这一点,您还应该覆盖 LogicalChildren 属性以返回内容。
希望能解决您的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.