2014-04-28 59 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