[英]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.