簡體   English   中英

WPF中通過組合框選擇的奇怪行為

[英]Strange behavior by combo box selection in wpf

我正在開發一個應用程序,其中有一個主窗口,該窗口在不同的停靠選項中有這么多的子窗口。 因此,一個擴展塢具有一個屬性面板窗口,該窗口允許用戶修改所選實體的屬性,並且在更改值后,用戶必須單擊控件底部的“應用”按鈕。 因此,我願意擁有某種功能,如果用戶修改了一些值,而不是單擊“應用”,那么如果用戶單擊除屬性面板視圖的子控件之外的其他位置,則應向用戶顯示一條消息,“請先單擊申請以保存您的更改”。 為此,我在MainWindow的mouse down事件上編寫了以下代碼。

private void MainWindow_MouseDown(object sender, MouseButtonEventArgs e)
{        
    var hitObject = this.InputHitTest(e.GetPosition(this)) as  DependencyObject;
    if (hitObject.FindVisualAncestor<PropertyPanelUserControl>() == null)
    {
        MessageBox.Show("Please save your changes");
    }        
}

因此,邏輯是這樣的,在主窗口上單擊鼠標,獲取命中的對象並檢查是否它是屬性面板控件的子控件,那么它將以PropertyPanelUserControl作為其父控件,而其他控件不是部件或子控件的PropertyPanelUserControl,然后將提示用戶單擊應用。

上面的代碼工作出色……但是我發現一個奇怪的問題,我在屬性面板中有一個組合框,其中的條目從1到10。因此,當用戶嘗試將值更改為其他值時,用戶不會顯示該消息,因為到目前為止,用戶正在單擊屬性面板控件,並且當我在組合框中選擇一個項目后在鼠標按下事件中檢查了命中對象時,命中對象是chromeButton或組合框。 但是,當我選擇最后一項10時,命中對象作為具有屬性面板控件的邊框出現。

<Border><View:PropertyPanelControl/></Border>及以上檢查失敗,因為border沒有祖先作為屬性面板控件,而border是控件的祖先。 因此,即使僅更改組合框的值,用戶仍會收到一條消息,而且,我確保我不在外部單擊組合框的項目,所以,現在的問題是,為什么wpf以這種奇怪的方式運行以及如何解決這個問題。

您的第一個問題很奇怪:

為什么WPF以這種奇怪的方式表現

您描述了會發生什么,這對我來說似乎完全正常。 用戶單擊一個ComboBoxItemHitTest告訴您您單擊了一個ComboBoxItem ……我在那里看不到任何問題。

如何解決這個問題

現在,我想像一下,如果您使用了ComboBoxItem並沿可視樹向上移動,那么您將找到PropertyPanelUserControl控件。 嘗試這樣的事情:

HitTestResult result = VisualTreeHelper.HitTest(this, e.GetPosition(this));
UIElement uIElement = result.VisualHit.GetParentOfType<PropertyPanelUserControl>();
if (uIElement != null)
{
    // the user clicked inside the PropertyPanelUserControl control
}

GetParentOfType方法是我創建的擴展方法,它在視覺樹中移動,以查找特定類型的第一個元素...如果願意,可以輕松地將其重構為普通方法:

public static T GetParentOfType<T>(this DependencyObject element) where T : DependencyObject
{
    Type type = typeof(T);
    if (element == null) return null;
    DependencyObject parent = VisualTreeHelper.GetParent(element);
    if (parent == null && ((FrameworkElement)element).Parent is DependencyObject) parent = ((FrameworkElement)element).Parent;
    if (parent == null) return null;
    else if (parent.GetType() == type || parent.GetType().IsSubclassOf(type)) return parent as T;
    return GetParentOfType<T>(parent);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM