wpf 实现childwindow

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 20:34   2461   0

1.问题:最近手上有个项目,需要用到wpf, wpf没有silverlight的childwindow, 这样弹窗口不是很方便

2.解决办法:整合了一下网上意见,得到解决办法如下:

public static class ChildWindowBehaviorRegist
{
public static void Show(this FrameworkElement control)
{
Grid grid = GetRootGrid(control );
RootAndMask ram = GetRootAndMask(control);

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

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

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

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

grid.Children.Add(control);

Storyboard scaleBoard = new Storyboard();

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

scaleBoard.Children.Add(scaleXAnimation);

Storyboard.SetTarget(scaleXAnimation, control);
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, control);
Storyboard.SetTargetProperty(scaleYAnimation, new PropertyPath("(UIElement.RenderTransform).(ScaleTransform.ScaleY)"));

scaleBoard.Begin();
};

opacityBoard.Begin();

grid.Children.Add(ram.MaskRectangle);
}
}

public static void Close(this FrameworkElement control)
{
Grid grid = GetRootGrid(control );
RootAndMask ram = GetRootAndMask(control);
if (grid != null)
{
ScaleTransform scaleTransform = new ScaleTransform(1.0, 1.0, control.Width / 2.0, control.Height / 2.0);
control.RenderTransform = scaleTransform;

Storyboard scaleBoard = new Storyboard();

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

scaleBoard.Children.Add(scaleXAnimation);

Storyboard.SetTarget(scaleXAnimation, control);
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, control);
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, ram.MaskRectangle);
Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("(Opacity)"));

opacityBoard.Completed += delegate
{
grid.Children.Remove(ram.MaskRectangle);
grid.Children.Remove(control);
};

opacityBoard.Begin();
};

scaleBoard.Begin();
}
}

static RootAndMask GetRootAndMask(FrameworkElement control)
{
if (control == null || control.Tag == null || !(control.Tag is RootAndMask))
return null;
return control.Tag as RootAndMask;
}

static Grid GetRootGrid(FrameworkElement control)
{
RootAndMask ram = GetRootAndMask(control);
FrameworkElement root = ram.Root ;

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;
}
}

public class RootAndMask
{
public FrameworkElement Root { get; set; }
public Rectangle MaskRectangle = new Rectangle { Fill = new SolidColorBrush(Colors.DarkGray), Opacity = 0.0 };
public RootAndMask(FrameworkElement root)
{
this.Root = root;
}
}

3.调用:使用很简单,

编写一个user control

Login{.....},

public MainWindow()
{
InitializeComponent();
user = new User();
client = new ChatClient(new InstanceContext(this ));
Login login = new Login(user ,client);
login.Tag = new RootAndMask(this);
login.Show();
}

4.利弊:

4.1 利:范围广, 只要是继承自FrameworkElement 的,你都可以像childwindow一样使用

4.2 弊: main page 需要 <mainpage><grid1><grid2></grid></grid><mainpage> 额外添加一个grid1,用grid2布局。tag被占用了。

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP