我们在WPF应用程序中使用自定义弹出。WPF本机弹出的问题是:
,
自定义弹出与本机WPF弹出的不同之处在于,它将弹出窗口的内容放在同一个窗口中的容器中,而不是放在新窗口中。内容是弹出窗口的逻辑子元素。因此,它解决了本机弹出问题与DataContext和DP继承。
我们的弹出窗口就像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>但是有一个带有绑定的bug。当在弹出窗口的内容中完成绑定时,绑定将无法工作。但是如果我们使用Snoop (https://github.com/snoopwpf/snoopwpf)并检查对象,那么绑定就可以正常工作。它使用数据文本或元素名称对每种类型的绑定执行此操作。
国际上,当窥探显示一个讨论区的DP列表时,如果它由于某种原因找到了绑定,就会删除它,并将它重新放回。所以我们想出了一个很难看的方法来使绑定工作。当弹出内容被加载时,我们沿着所有的可视子程序走,通过反射获得他们所有的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);
}
}
}有没有人知道这个问题是从哪里来的,如何以更清洁的方式解决它?
发布于 2020-03-30 17:35:40
Snoop不移除和重新应用绑定。它所做的是创建新的绑定,这些绑定绑定到对象/控件的DependencyProperties,这将导致再次评估绑定。
您编写的是要将内容添加到逻辑树中,如果通过调用AddLogicalChild来实现这一点,您还应该重写LogicalChildren属性以返回内容。
希望这能解决你的问题。
https://stackoverflow.com/questions/60413391
复制相似问题