0

私はこれと数日間戦っていますが、答えが見つかりません。ここの誰かが助けてくれることを願っています。

ユーザーがキーボード入力を必要とする Textblock コントロールを選択するとポップアップするアニメーション キーボードがあります。キーボードをアニメーション化するコードは問題ありません。ただし、テキストブロック コントロールを含むグリッドを調整するコードを呼び出して、テキストブロック コントロールが常にアニメーション化されたキーボードのすぐ上に配置されるようにします。私が見ている問題は、グリッドを含むページを閉じると、パス '(0).(1)[0].(2)' の 'Children' プロパティ値で例外が発生し、不変インスタンスを指すことです。この行の 'System.Windows.Media.TransformCollection' の:
_AppWindowControl.IsEnabled = false;

キーボードが取り外されたときに呼び出されるコード (「完了」キーを押すと隠されます) は次のとおりです。

    /// <summary>
    /// Animation to hide keyboard
    /// </summary>
    private void HideKeyboard()
    {
            if (_verticalOffset != 0)
            {
                TranslateTransform tt = new TranslateTransform();
                DoubleAnimation slide = new DoubleAnimation(_verticalOffset, 0, TimeSpan.FromMilliseconds(400));
                var name = "myTransform" + tt.GetHashCode();
                _mainGrid.RegisterName(name, tt);
                name = "mySlide" + slide.GetHashCode();
                _mainGrid.RegisterName(name, slide);
                _mainGrid.RenderTransform = tt;
                tt.BeginAnimation(TranslateTransform.YProperty, slide);
                _verticalOffset = 0;
            }

            Storyboard sb = (Storyboard)this.TryFindResource("HideKeyboard");
            sb.Completed += new EventHandler(HideKeyboard_Completed);
            sb.Begin(this);
    }

問題が解決することを期待して、名前の登録を追加しました。しかし、そうではありません。割り当てを削除すると_mainGrid.RenderTransform = tt;、appWindow はエラーなしで閉じます。

また、キーボードを閉じるときに問題が発生すると言いました。このコードは、表示するのが最も簡単でした。キーボードが表示されると、AdjustScreen が呼び出され、_mainGrid.RenderTransform への TranslateTransform の同様の割り当てが作成されます。ここでも、割り当てを削除しても問題は発生しません (アニメーションも発生しません)。そうしないと、上記と同じエラーが発生します。

どんな助けでも大歓迎です。ありがとう!

編集。xaml ファイルの StoryBoard は次のとおりです。

        <Storyboard x:Key="HideKeyboard">
        <DoubleAnimationUsingKeyFrames AccelerationRatio=".75" BeginTime="00:00:00" DecelerationRatio=".25" Storyboard.TargetName="KeyboardGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0" />
            <!--<SplineDoubleKeyFrame KeyTime="00:00:00.20" Value="-10" />-->
            <!--<SplineDoubleKeyFrame KeyTime="00:00:00.45" Value="450" />-->
            <SplineDoubleKeyFrame KeyTime="00:00:00.25" Value="450" />
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>`enter code here`

また、ここで変更する前に _mainGrid.RenderTransfrom を基本的に保存する回避策があります。次に、HideKeybaord_Completed ハンドラーが呼び出されると、元に戻します。この方法は機能します。しかし、それはかなりハックのようです。

クラッシュはアプリケーションのクラッシュです。ほとんどの場合、とにかく UI を終了しているので、誰も気付かない. しかし、モデルに新しいビューを追加していると、ビューを閉じるときにクラッシュし、以前のビューに戻りません。

4

2 に答える 2

0

仮想キーボードのような動作を作成しようとしました

xaml

<StackPanel xmlns:l="clr-namespace:CSharpWPF">
    <StackPanel.Resources>
        <UniformGrid Columns="5"
                     Rows="2"
                     x:Key="dummyKeyboard">
            <Button Content="1" />
            <Button Content="2" />
            <Button Content="3" />
            <Button Content="4" />
            <Button Content="5" />
            <Button Content="A" />
            <Button Content="B" />
            <Button Content="C" />
            <Button Content="D" />
            <Button Content="E" />
        </UniformGrid>
    </StackPanel.Resources>
    <TextBox Text="regular textbox" />
    <TextBox Text="virtual keyboard enabled textbox"
             l:InputProvider.VirtualKeyboard="{StaticResource dummyKeyboard}" />
    <TextBox Text="another regular textbox" />
    <TextBox Text="another virtual keyboard enabled textbox"
             l:InputProvider.VirtualKeyboard="{StaticResource dummyKeyboard}" />
    <TextBox Text="one more regular textbox" />
</StackPanel>

例として、いくつかのボタンを含むダミー キーボードを定義しました。次に、設定によってこのキーボードをいくつかのInputProvider.VirtualKeyboard="{StaticResource dummyKeyboard}"テキストボックスに割り当てました。手動ですべてに割り当てることも、テキストボックスのスタイルを介して割り当てることもできます

InputProvider クラス

namespace CSharpWPF
{
    public class InputProvider : DependencyObject
    {
        public static object GetVirtualKeyboard(DependencyObject obj)
        {
            return (object)obj.GetValue(VirtualKeyboardProperty);
        }

        public static void SetVirtualKeyboard(DependencyObject obj, object value)
        {
            obj.SetValue(VirtualKeyboardProperty, value);
        }

        // Using a DependencyProperty as the backing store for VirtualKeyboard.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty VirtualKeyboardProperty =
            DependencyProperty.RegisterAttached("VirtualKeyboard", typeof(object), typeof(InputProvider), new PropertyMetadata(null, OnVirtualKeyboardChanged));

        private static void OnVirtualKeyboardChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TextBox tb = d as TextBox;
            tb.GotFocus += (sender, ee) => OpenPopup(sender as TextBox);
            tb.LostFocus += (sender, ee) => ((Popup)tb.GetValue(PopupProperty)).IsOpen = false;
        }

        private static void OpenPopup(TextBox textBox)
        {
            Popup popup = new Popup() { Child = new ContentControl() { Content = GetVirtualKeyboard(textBox), Focusable = false } };
            FocusManager.SetIsFocusScope(popup.Child, true);
            popup.PlacementTarget = textBox;
            popup.AllowsTransparency = true;
            popup.PopupAnimation = PopupAnimation.Slide;
            textBox.SetValue(PopupProperty, popup);
            popup.IsOpen = true;
        }

        // Using a DependencyProperty as the backing store for Popup.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PopupProperty =
            DependencyProperty.RegisterAttached("Popup", typeof(Popup), typeof(InputProvider), new PropertyMetadata(null));
    }
}

このクラスは、オブジェクト型の添付プロパティ VirtualKeyboard を定義しているため、必要に応じてデータ テンプレートを定義できます。

したがって、このクラスは、テキスト ボックスの GotFocus および LostFocus イベントをリッスンし、スライド アニメーションで仮想キーボードを表示または非表示にします。

これを試してみてください。これが希望を達成するのに役立つことを願っています。

ダミー キーボードは実際にはダミーであり、入力を行わないことに注意してください。プロジェクトに同じものを実装するときに、実際に動作する仮想キーボードと同じものを置き換える必要があります。

于 2014-08-06T05:30:52.793 に答える