【问题标题】:FlipView crashes when touched触摸时 FlipView 崩溃
【发布时间】:2013-01-05 04:34:39
【问题描述】:

在 Windows 应用商店应用中

XAML

<Page
    x:Class="FunctionTest.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:FunctionTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Page.Resources>
        <Storyboard x:Name="FloatingFlipOver">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.GlobalOffsetZ)" Storyboard.TargetName="FloatingRoot">
                <EasingDoubleKeyFrame KeyTime="0" Value="-2000"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="0">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <QuarticEase/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="FloatingRoot">
                <EasingDoubleKeyFrame KeyTime="0" Value="180"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.8" Value="0">
                    <EasingDoubleKeyFrame.EasingFunction>
                        <QuarticEase/>
                    </EasingDoubleKeyFrame.EasingFunction>
                </EasingDoubleKeyFrame>
            </DoubleAnimationUsingKeyFrames>
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="FloatingRoot">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Page.Resources>

    <Grid>        
        <Grid x:Name="FloatingRoot" Visibility="Collapsed" Width="500" Height="300">
            <Grid.Projection>
                <PlaneProjection  CenterOfRotationX="0.5" CenterOfRotationY="0.5"/>
            </Grid.Projection>
            <Rectangle x:Name="FloatingBackground" Fill="SkyBlue" />
            <FlipView>
                <Grid x:Name="FloatingContainer" Width="300" Height="300">

                </Grid>
            </FlipView>
        </Grid>
        <Button Content="Test" HorizontalAlignment="Left" Margin="46,36,0,0" VerticalAlignment="Top" Click="Test_Click"/>
    </Grid>
</Page>

代码

private void Test_Click(object sender, RoutedEventArgs e)
{
    Button msiBtn = new Button();
    msiBtn.Content = "addBtn";
    msiBtn.Width = 100; msiBtn.Height = 50;
    msiBtn.Tapped += msiBtn_Tapped;
    FloatingContainer.Children.Add(msiBtn);
    FloatingRoot.Opacity = 0;
    FloatingRoot.Visibility = Visibility.Visible;
    FloatingFlipOver.Begin();
}

void msiBtn_Tapped(object sender, TappedRoutedEventArgs e)
{
    FloatingRoot.Visibility = Visibility.Collapsed;
    FloatingContainer.Children.Clear();
}

这在与鼠标一起使用时有效, 但是当我触摸添加在 FloatingContainer 中的按钮时它会崩溃, 有时,即使我触摸 FloatingContainer(不是按钮),它也会崩溃。 是bug吗?

【问题讨论】:

    标签: windows-8 microsoft-metro windows-runtime winrt-xaml windows-store-apps


    【解决方案1】:

    我想你的意思是崩溃,而不是崩溃,对吧?因为这就是我所看到的。

    存在与 ScrollViewers 和投影相关的已知错误。我不确定它是否被公开讨论过,但是我在 WinRT XAML 工具包(在 FlipAnimation 中)中听说的一种解决方法对我有用,因为 FlipView 有一个 ScrollViewer 作为其模板的一部分,因此似乎也适用于您的情况。基本上,您需要将 ScrollViewer 的 ZoomMode 更改为其他内容并返回,然后它可以正常工作而不会崩溃。为了修复 sn-p 中的代码,我引用了 WinRT XAML Toolkit 以使用 VisualTreeHelperExtensions 帮助提取 ScrollViewer 并在动画完成后来回更改 ZoomMode,如下所示:

    using WinRTXamlToolkit.Controls.Extensions;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Input;
    
    namespace App96
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private void Test_Click(object sender, RoutedEventArgs e)
            {
                Button msiBtn = new Button();
                msiBtn.Content = "addBtn";
                msiBtn.Width = 100; msiBtn.Height = 50;
                msiBtn.Tapped += msiBtn_Tapped;
                FloatingContainer.Children.Add(msiBtn);
                FloatingRoot.Opacity = 0;
                FloatingRoot.Visibility = Visibility.Visible;
                FloatingFlipOver.Begin();
                FloatingFlipOver.Completed -= FloatingFlipOver_Completed;
                FloatingFlipOver.Completed += FloatingFlipOver_Completed;
            }
    
            void FloatingFlipOver_Completed(object sender, object e)
            {
                foreach (var sv in FloatingRoot.GetDescendantsOfType<ScrollViewer>())
                {
                    sv.ZoomMode = (ZoomMode)(((int)sv.ZoomMode + 1) % 2);
                    sv.ZoomMode = (ZoomMode)(((int)sv.ZoomMode + 1) % 2);
                }
            }
    
            void msiBtn_Tapped(object sender, TappedRoutedEventArgs e)
            {
                FloatingRoot.Visibility = Visibility.Collapsed;
                FloatingContainer.Children.Clear();
            }
        }
    }
    

    如果您不想要整个 Toolkit,可以使用 VisualTreeHelperExtensions 的相关位:

    public static class VisualTreeHelperExtensions
    {
        public static IEnumerable<T> GetDescendantsOfType<T>(this DependencyObject start) where T : DependencyObject
        {
            return start.GetDescendants().OfType<T>();
        }
    
        public static IEnumerable<DependencyObject> GetDescendants(this DependencyObject start)
        {
            var queue = new Queue<DependencyObject>();
            var count = VisualTreeHelper.GetChildrenCount(start);
    
            for (int i = 0; i < count; i++)
            {
                var child = VisualTreeHelper.GetChild(start, i);
                yield return child;
                queue.Enqueue(child);
            }
    
            while (queue.Count > 0)
            {
                var parent = queue.Dequeue();
                var count2 = VisualTreeHelper.GetChildrenCount(parent);
    
                for (int i = 0; i < count2; i++)
                {
                    var child = VisualTreeHelper.GetChild(parent, i);
                    yield return child;
                    queue.Enqueue(child);
                }
            }
        }
    }
    

    【讨论】:

    • 这是解决一个非常痛苦的错误的好方法。在我的例子中,我们只需要设置可见性并重置。
    • 谢谢!这个问题使我的整个应用程序崩溃,并且只抛出一个非常模糊的错误消息。您的解决方案完全修复了它 - 不错。奇怪的是,我曾经在早期的 Titanium SDK 中遇到过几乎相同的问题 - 必须等待 SDK 更新才能解决这个问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多