在页面之间导航时使用Kinect工具箱和磁性控件



我使用的是Kinect.Toolbox鼠标和磁性控件。它在一页纸上运行得非常好。然而,当我有不同的页面在它们之间导航时,我会得到一个错误:用户代码中的InvalidOperationException Unhanded-指定的可视化不是该可视化中的祖先。这种情况发生在MouseController.cs第158行:

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

经过一些调试,我了解到上一页的磁性控件仍在列表中,这就是问题的原因。所以我试着在导航到下一页之前清除它们:

MouseController.Current.MagneticsControl.Clear();

然而,我还是犯了同样的错误。如果我在导航前清除列表,我会收到错误,因为我仍然在同一页上,而magneticControls列表变空;如果我在浏览后清除它们,我不会收到错误,但我的magneticControls不会被识别,因为它们是从列表中清除的。有人能解决这个问题吗?清除此列表的正确位置在哪里?

这是我有磁性控件的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);
}

好吧,我这样解决了我的问题:我知道这个问题是因为在组装可视化树时调用了转换器,因此您的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);

相关内容

  • 没有找到相关文章

最新更新