2014-04-28 138 views
0

我正在研究一個應用程序,其中我們有一個主窗口,在不同的碼頭選項中有這麼多子窗口。所以,一個碼頭有一個屬性面板窗口,它允許用戶修改所選實體的屬性,並且在改變該值之後,用戶必須點擊控件底部可用的應用按鈕。所以,我願意擁有某種功能,如果用戶修改了某些值,而不是點擊apply,如果用戶單擊屬性面板視圖的子控件之外的其他位置,則應該給用戶一條消息:「請先點擊申請保存您的更改「。爲此,我在MainWindow的鼠標按下事件中編寫了以下代碼片段。wpf中組合框選擇的奇怪行爲

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>以上檢查失敗,因爲邊界不具有作爲屬性面板控件的祖先,而是邊界是控件的祖先。因此,即使只更改組合框值,用戶也會收到一條消息, 此外,我已確認我沒有在外部單擊組合框項目,所以,現在問題是爲什麼wpf以這種奇怪的方式行事,以及如何解決這個問題。

回答

1

你的第一個問題是奇怪:

爲什麼WPF中

你所描述的情況,這一切似乎完全正常我這奇怪的方式表現。用戶點擊一個ComboBoxItem,你的HitTest告訴你,你點擊了一個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); 
} 
+0

,我想你誤會了,我是說,當我選擇在組合框中的任何項目,比去年元素之外,那麼它給我combbox但對最後一個元素,它給了邊境控制,有屬性面板控制.... –

+0

其實,它是我的錯誤,我無法以適當的方式解釋問題...... –

+0

不,我沒有誤解任何東西......我的觀點是,當你點擊由小部件組成的UI元素時,你可能會點擊其中一個較小的部分(例如'Border')。但是,「邊框」仍然是父控制的一部分。因此,您仍然應該能夠在視覺樹上上下移動並找到包含的控件。也許閱讀CodeProject上的[瞭解WPF中的可視化樹和邏輯樹](http://www.codeproject.com/Articles/21495/Understanding-the-Visual-Tree-and-Logical-Tree-in)文章可以提供幫助你更好地理解這一點。 – Sheridan