簡體   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