0

我正在使用 Kinect.Toolbox 鼠标和磁性控件。它在单个页面中运行良好。但是,当我有不同的页面在它们之间导航时,我收到一个错误:InvalidOperationException Unhandeled in user code - 指定的视觉对象不是此视觉对象的祖先。这发生在 MouseController.cs 第 158 行:

var position = element.TransformToAncestor(rootVisual).Transform(new Point(0, 0));

通过一些调试,我了解到上一页中的磁性控制器仍在列表中,这导致了问题。所以我尝试在导航到下一页之前清除它们:

MouseController.Current.MagneticsControl.Clear();

但是,我仍然得到同样的错误。如果我在导航之前清除列表我会收到错误,因为我仍在同一页面中并且磁力控制列表为空,如果我在导航后清除它们我没有收到错误但我的磁力控制器没有得到识别因为他们从列表中清除。有人对此有解决方案吗?清除此列表的正确位置在哪里?

这是我有磁性控件的 XAML:

 <Grid>
    <Button Content="1" local:MagneticPropertyHolder.IsMagnetic="True" Click="Button_Click"/> 
</Grid>

在 Button_Click 上,我导航到另一个页面,该页面也有一些磁性控制:

private void Button_Click(object sender, RoutedEventArgs e)
    {
        MouseController.Current.MagneticsControl.Clear();
        keyboard pageKeyboard = new keyboard();
        NavigationService navigationService = NavigationService.GetNavigationService(this);
        navigationService.Navigate(pageKeyboard);
    }
4

1 回答 1

0

好的,我这样解决了我的问题:我知道这个问题是因为在可视化树仍在组装时调用了转换器,因此您的 Visual 还不是 Window 的后代。有一些解决方案,例如在您的可视化树已经构建后进行转换。这是通过使用 Dispatcher.BeginInvoke(DispatcherPriority.Render, ...) 注册 Dispatcher 回调并在回调中完成您的工作来完成的。

由于我不想深入研究源代码,而且 WPF 还不足以完成高级复杂的工作,所以我使用了自己的解决方案,这可能不是有史以来最好的解决方案。而不是清除磁性控制列表,我决定以编程方式设置我的磁性控制,而不是在 XAML 中设置它们。通过这种方式,我可以确保在已经构建视觉树时设置磁性控件。因此,在 Page_Loaded 事件中,我设置了磁控并将它们推入磁控列表(不确定最后一部分是否必要):

private void Page_Loaded(object sender, RoutedEventArgs e)
{
  foreach (Button btn in MagneticButtons)
        {
            btn.SetValue(MagneticPropertyHolder.IsMagneticProperty, true);
            MouseController.Current.MagneticsControl.Add(btn);
        }
}

由于我唯一的磁性控件是按钮,因此您也可以像这样设置其他控件。当我从页面导航到另一个页面时,我取消了所有磁性按钮并将它们从磁性控制列表中删除:

foreach (Button btn in MagneticButtons)
{
    btn.SetValue(MagneticPropertyHolder.IsMagneticProperty, false);
    MouseController.Current.MagneticsControl.Remove(btn);
}

要获取窗口或页面中的控件,您可以使用以下命令:

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
    {
        if (depObj != null)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in FindVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

在我的情况下,例如获取按钮:

private IEnumerable<Button> MagneticButtons = FindVisualChildren<Button>(this);
于 2012-10-03T13:28:25.903 回答