WPF'Children'属性值在路径'(0)。(1)[0]。(2)'指向'System.Windows.Media.TransformCollection'的不可变实例

时间:2014-08-04 04:04:52

标签: wpf rendertransform

我一直在争取这几天,但是找不到答案。希望有人可以提供帮助。

当用户选择需要键盘输入的Textblock Control时,我们会弹出一个动画键盘。动画键盘的代码很好。但它调用代码来调整包含文本块控件的网格,以便文本块控件始终位于动画键盘的正上方。我看到的问题是,当包含网格的页面关闭时,它与“孩子们”的例外情况有关。路径中的属性值'(0)。(1)[0]。(2)'指向System.Windows.Media.TransformCollection'的不可变实例。在这条线上:
_AppWindowControl.IsEnabled = false;

删除键盘时调用的代码(由" Done" keypress隐藏)是这样的:

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

崩溃是应用程序崩溃。大多数时候,我们仍在退出用户界面,所以没有人注意到。但是,当我为模型添加新视图时,它会在关闭我的视图时崩溃,因此它不会返回到上一个视图。

2 个答案:

答案 0 :(得分:1)

如果您没有为要设置动画的对象定义一个TransformGroup作为RenderTransform,则会出现此错误。它应该看起来像这样:

<Ellipse>
    <Ellipse.RenderTransform>
        <TransformGroup>
            <ScaleTransform CenterX="0.5" CenterY="0.5" />
            <SkewTransform/>
            <RotateTransform/>
            <TranslateTransform/>
        </TransformGroup>
    </Ellipse.RenderTransform>
</Ellipse>

答案 1 :(得分: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>

例如,我已经定义了一个包含一些按钮的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&amp;文本框的LostFocus事件,并以滑动动画显示或隐藏虚拟键盘。

尝试一下,希望这可以帮助你实现所需。

请注意,虚拟键盘非常虚拟,不会进行任何输入,在项目中实现相同功能时,需要将其替换为实际工作的虚拟键盘。