2

只需将其记录为问题答案,以便其他人不必遭受同样的痛苦。

我有一个为页面设置动画的 WPF 应用程序,就像在 iPhone 上滑动一样。一切都很好,直到其中一个页面需要包含 WebBrowser。它对动画完全没有反应——当它应该滑入时,直到你聚焦它才会出现,当它应该滑出时,它会消失,直到你将鼠标移到它上面。在这两种情况下,它只是弹出/弹出而不是动画。

使事情复杂化的是,在项目期间,出于不相关的原因,决定回到 .net 3.5 而不是 4。

所以问题是:我怎样才能(a)让 WebBrowser 正确地制作动画;或 (b) 如何在动画开始时隐藏 WebBrowser 并在结束时再次显示。动画目前是在 XAML 中定义的,我并不是特别想将其更改为代码。

一个后续问题是:有没有更好的方法,仍然使用 .net 3.5?

4

1 回答 1

2

更新与 WinForms 相比,WPF WebBrowser 实在是太可悲了,我已经使用 WindowsFormsHost 进行了替换。下面的一切仍然适用,但 WebBrowser 现在不那么高贵了(例如,它有一个 DocumentCompleted 事件)。


我很快放弃了为 WebBrowser 设置动画的选项,因为它太难了,而是决定隐藏并重新显示它。动画的开始由视图模型上的命令触发。然后它找到应该显示的页面,创建它,并通过反映过渡状态的附加属性启动动画。

我创建了一个接口 ,IRequireTransitionInfo这样调用给它一个隐藏自己并再次显示IRequireTransitionInfo.TransitioningFrom的机会。IRequireTransitionInfo.TransitioningToTransitioningFrom 很简单,但必须在情节提要完成时调用 TransitioningTo。

最初,在 View Model 的构造函数中,它去寻找 Storyboard 并连接到它的 Completed 事件中,如下面的代码所示:

    Storyboard animation = Application.Current.FindResource("SlideAnimation") as Storyboard;
    if (animation != null)
    {
      animation.Completed += new EventHandler(animation_Completed);
    }

然后是事件处理程序:

void animation_Completed(object sender, EventArgs e)
{
  IRequireTransitionInfo info = currentViewModel as IRequireTransitionInfo;
  if (info != null)
    info.TransitioningTo(currentView);
}

这似乎与 .net 4 配合得很好。降级到 .net 3.5 后,当上面连接 Completed 事件的代码运行时,我收到以下错误:

Specified value of type 'System.Windows.Media.Animation.Storyboard' must have IsFrozen set to false to modify.

尽管有一些关于 SO 的其他答案,但您无法解冻冻结的 Freezable,并且将代码移动到 MainWindow 的构造函数中并没有帮助。

我沿着故事板上的附加属性的路径走下去,该属性绑定到视图模型上的命令。

<Storyboard x:Key="SlideAnimation" local:EventCommand.StoryboardCompleted="{Binding Source={StaticResource Locator}, Path=Current.MainViewModel.StoryboardCompletedCommand}">

但是,这会在运行时导致以下错误:

Cannot convert the value in attribute 'ContentTemplate' to object of type 'System.Windows.DataTemplate'. Cannot freeze this Storyboard timeline tree for use across threads.

看来您不能在 Storyboard 上进行任何数据绑定(至少在 .net 3.5 下)。因此,我通过让附加属性只定义资源的字符串名称来稍微不雅地解决了这个问题,该资源预计将实现支持故事板完成通知的接口。

<Storyboard x:Key="SlideAnimation" local:EventCommand.StoryboardCompletedHandler="Locator">

如果有人知道在 .net 3.5 下处理这种情况的更好方法,我会很高兴听到。

于 2012-07-12T04:35:49.807 回答