0

Kinect.Toolboxマウスと磁気コントロールを使用しています。1ページで問題なく動作します。ただし、ページ間を移動するページが異なると、次のエラーが発生します。InvalidOperationExceptionユーザーコードで処理されません-指定されたビジュアルは、このビジュアルの祖先ではありません。これはMouseController.csの158行目で発生します:

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

いくつかのデバッグで、前のページの磁気制御装置がまだリストにあり、それが問題の原因であることがわかりました。そこで、次のページに移動する前に、それらをクリアしてみました。

MouseController.Current.MagneticsControl.Clear();

ただし、それでも同じエラーが発生します。ナビゲートする前にリストをクリアすると、同じページにいて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);
    }
4

1 に答える 1

0

OK、私はこのように問題を解決しました。この問題は、ビジュアルツリーがまだアセンブルされている間にコンバーターが呼び出されているために発生しているため、ビジュアルはまだウィンドウの子孫ではないことを理解しました。ビジュアルツリーがすでに構築された後で変換を行うなど、いくつかの解決策があります。これは、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 に答える