首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于WPF的Silverlight ChildWindow

用于WPF的Silverlight ChildWindow
EN

Stack Overflow用户
提问于 2010-02-09 07:23:29
回答 4查看 10.1K关注 0票数 11

有没有可能在Silverlight中做一个像ChildWindow一样的ChildWindow,但是用在WPF上呢?我试图使Silverlight ChildWindow适应WPF,但遇到了转换的问题,并且无法设置弹出窗口的父窗口。我正在尝试做一些类似工作的东西,这样我就不必为弹出窗口向XAML添加代码。有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-02-10 05:44:24

这个类应该做你想做的事情:

代码语言:javascript
复制
public class SilverlightishPopup
{
    private Rectangle maskRectangle = new Rectangle { Fill = new SolidColorBrush(Colors.DarkGray), Opacity = 0.0 };

    public FrameworkElement Parent
    {
        get;
        set;
    }

    public FrameworkElement Content
    {
        get;
        set;
    }

    public SilverlightishPopup()
    {
        Button button = new Button();
        button.Width = 100;
        button.Height = 200;
        button.Content = "I am the popup!";

        button.Click += delegate { Close(); };

        Content = button;
    }

    public void Show()
    {
        Grid grid = GetRootGrid();

        if (grid != null)
        {
            DoubleAnimation opacityAnimation = new DoubleAnimation(0.5, new Duration(TimeSpan.FromSeconds(0.5)));

            Storyboard opacityBoard = new Storyboard();
            opacityBoard.Children.Add(opacityAnimation);

            Storyboard.SetTarget(opacityAnimation, maskRectangle);
            Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("(Opacity)"));

            opacityBoard.Completed += delegate
            {
                ScaleTransform scaleTransform = new ScaleTransform(0.0, 0.0, Content.Width / 2.0, Content.Height / 2.0);
                Content.RenderTransform = scaleTransform;

                grid.Children.Add(Content);

                Storyboard scaleBoard = new Storyboard();

                DoubleAnimation scaleXAnimation = new DoubleAnimation(1.0, TimeSpan.FromSeconds(0.5));

                scaleBoard.Children.Add(scaleXAnimation);

                Storyboard.SetTarget(scaleXAnimation, Content);
                Storyboard.SetTargetProperty(scaleXAnimation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));

                DoubleAnimation scaleYAnimation = new DoubleAnimation(1.0, TimeSpan.FromSeconds(0.5));

                scaleBoard.Children.Add(scaleYAnimation);

                Storyboard.SetTarget(scaleYAnimation, Content);
                Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));

                scaleBoard.Begin();
            };

            opacityBoard.Begin();

            grid.Children.Add(maskRectangle);
        }
    }

    public void Close()
    {
        Grid grid = GetRootGrid();

        if (grid != null)
        {
            ScaleTransform scaleTransform = new ScaleTransform(1.0, 1.0, Content.Width / 2.0, Content.Height / 2.0);
            Content.RenderTransform = scaleTransform;

            Storyboard scaleBoard = new Storyboard();

            DoubleAnimation scaleXAnimation = new DoubleAnimation(0.0, TimeSpan.FromSeconds(0.5));

            scaleBoard.Children.Add(scaleXAnimation);

            Storyboard.SetTarget(scaleXAnimation, Content);
            Storyboard.SetTargetProperty(scaleXAnimation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleX)"));

            DoubleAnimation scaleYAnimation = new DoubleAnimation(0.0, TimeSpan.FromSeconds(0.5));

            scaleBoard.Children.Add(scaleYAnimation);

            Storyboard.SetTarget(scaleYAnimation, Content);
            Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));

            scaleBoard.Completed += delegate
            {
                DoubleAnimation opacityAnimation = new DoubleAnimation(0.5, 0.0, new Duration(TimeSpan.FromSeconds(0.5)));

                Storyboard opacityBoard = new Storyboard();
                opacityBoard.Children.Add(opacityAnimation);

                Storyboard.SetTarget(opacityAnimation, maskRectangle);
                Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("(Opacity)"));

                opacityBoard.Completed += delegate
                {
                    grid.Children.Remove(maskRectangle);
                    grid.Children.Remove(Content);
                };

                opacityBoard.Begin();
            };

            scaleBoard.Begin();
        }
    }

    private Grid GetRootGrid()
    {
        FrameworkElement root = Parent;

        while (root is FrameworkElement && root.Parent != null)
        {
            FrameworkElement rootElement = root as FrameworkElement;

            if (rootElement.Parent is FrameworkElement)
            {
                root = rootElement.Parent as FrameworkElement;
            }
        }

        ContentControl contentControl = root as ContentControl;

        return contentControl.Content as Grid;
    }
}

只需将Parent属性设置为父窗口中的任何Framework元素(它将找到用掩码阻止它的窗口),并将内容设置为您希望弹出的任何内容(当然,当您希望显示它时,还可以调用Show方法)。你必须自己想出弹出式包装器(即带有边框和调用close方法的close按钮的东西),但这应该不难,而且显然要移除构造器中的占位符按钮(它只是为了向你展示它的外观)。

唯一的问题是它只能在有内容的窗口上工作(例如,在Silverlight中被命名为"LayoutRoot“的东西)是一个网格(当你创建一个新的WPF/Silverlight窗口/页面时,这是默认的)。我将它设置为适用于所有面板,但当与StackPanel或DockPanel一起使用时,它看起来很奇怪(不出所料)。如果对你不起作用,让我知道,我们会想出办法的。

如果您使用它,您可能可以使动画看起来更接近原始弹出窗口(可能使用一些缓动)。也许还有一种更好的方法来找到根,我只是匆匆想出了这个方法,但我认为它会起作用的(尽管同样,只有内容设置为网格的Contentcontrol )。

如果你有任何疑问/问题,请告诉我,我希望这能解决你的问题。

票数 9
EN

Stack Overflow用户

发布于 2010-03-24 16:36:47

看一看BubbleBurst Sourcecode。GameOverView的功能完全符合您的要求。

票数 2
EN

Stack Overflow用户

发布于 2010-02-09 08:38:44

只需从窗口派生并从父窗口调用ShowDialog即可。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2225654

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档