繁体   English   中英

WPF:绑定仅在使用 Snoop 时有效

[英]WPF : Binding only working when using Snoop

我们在 WPF 应用程序中使用自定义弹出窗口。 WPF 本机弹出窗口的问题在于:

  • 它使用了一个新的 Windown,因此内容最终会出现在另一个可视化树中,这使得转换计算更加复杂,并且您无法控制 Zindex。 它永远是最重要的。
  • 内容丢失了 DataContext 和所有继承的属性或资源。

我们的自定义弹出窗口与原生 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM