11

SilverlightでChildWindowのようなChildWindowを作成することは可能ですか?ただし、WPF用ですか?Silverlight ChildWindowをWPFに適合させようとしましたが、変換で問題が発生し、ポップアップの親を設定できませんでした。ポップアップ用にXAMLにコードを追加する必要がないように、同じように機能するものを作成しようとしています。何か案は?

4

4 に答える 4

9

このクラスは、あなたがやりたいことをするべきです:

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 プロパティを親ウィンドウの任意のフレームワーク要素に設定するだけで (マスクでブロックする Window が見つかります)、コンテンツをポップアップしたいものに設定します (必要なときに Show メソッドを呼び出します)。もちろん表示されます)。ポップアップ ラッパー (つまり、ボーダーと close メソッドを呼び出す閉じるボタンを備えたもの) を独自に作成する必要がありますが、難しくはなく、明らかにコンストラクターのプレースホルダー ボタンを削除します。 (それがどのように見えるかを示すためにそこにあるだけです)。

これに関する唯一の問題は、コンテンツ (つまり、Silverlight で「LayoutRoot」と呼ばれるもの) がグリッド (新しい WPF/Silverlight ウィンドウ/ページを作成するときのデフォルト) であるウィンドウでのみ機能することです。すべてのパネルで機能するように設定しましたが、StackPanel または DockPanel で使用すると (予想どおり) 奇妙に見えます。それがうまくいかない場合は、私に知らせてください。

これをいじってみると、おそらくアニメーションを元のポップアップに近づけることができます (おそらくイージングを使用します)。ルートを見つけるためのより良い方法もあるかもしれません.その場でその方法を思いついたのですが、うまくいくと思います.

ご質問や問題がありましたらお知らせください。これで問題が解決することを願っています。

于 2010-02-09T21:44:24.010 に答える
2

BubbleBurstのソースコードを見てください。GameOverView はまさにあなたが探していることを行います。

于 2010-03-24T08:36:46.617 に答える
1

ここで拡張WPFツールキットで利用可能なChildWindowコントロールを参照して くださいhttp://wpftoolkit.codeplex.com/wikipage?title=ChildWindow&referringTitle=Home

于 2011-08-15T15:53:37.493 に答える
1

Windowから派生し、親ウィンドウからShowDialogを呼び出すだけです。

于 2010-02-09T00:38:43.950 に答える