0

我已经为此奋斗了几天,只是找不到答案。希望这里有人可以提供帮助。

我们有一个动画键盘,当用户选择需要键盘输入的 Textblock 控件时会弹出。动画键盘的代码很好。但它调用代码来调整包含 textblock 控件的网格,以便 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,它会创建类似的 TranslateTransform 分配给 _mainGrid.RenderTransform。同样,如果我删除分配,则不会出现问题(也不会出现动画)。否则,将发生上述相同的错误。

任何帮助将不胜感激。谢谢!

编辑。这是 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 处理程序时,它会将其还原。这种方法有效。但这似乎很hackish。

崩溃是应用程序崩溃。大多数时候,我们无论如何都会退出 UI,所以没有人注意到。但是,当我向模型添加一个新视图时,它会在关闭我的视图时崩溃,因此它不会返回到以前的视图。

4

2 回答 2

1

如果您没有将 TransformGroup 定义为您正在制作动画的事物的 RenderTransform,则可能会出现此错误。它应该看起来像这样:

<Ellipse>
    <Ellipse.RenderTransform>
        <TransformGroup>
            <ScaleTransform CenterX="0.5" CenterY="0.5" />
            <SkewTransform/>
            <RotateTransform/>
            <TranslateTransform/>
        </TransformGroup>
    </Ellipse.RenderTransform>
</Ellipse>
于 2018-11-28T14:02:45.480 回答
0

我试图做出一种虚拟键盘的行为

xml

<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>

例如,我定义了一个包含一些按钮的 dummyKeyboard。然后我通过设置将此键盘分配给某些文本框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,它是 object 类型的,因此允许您根据需要定义数据模板

所以这个类监听文本框的 GotFocus 和 LostFocus 事件,并以滑动动画显示或隐藏虚拟键盘。

试一试,我希望这可以帮助您实现预期。

请注意,虚拟键盘实际上是虚拟的,它不会进行任何打字,您需要在项目中实现相同的虚拟键盘时将其替换为实际工作的虚拟键盘。

于 2014-08-06T05:30:52.793 回答