ChildWindow:Popup的加强版

Silverlight项目中少不了弹出窗口,Silverlight中提供了ChildWindow作为弹出窗口,已经能满足大部分需求。 但是ChildWindow模板并不好看,而且位置总是居中,很难通过Transform来控制。为了进一步了解ChildWindow控件,我反编译了ChildWindow的源代码,一探究竟。发现ChildWindow其实可以很强大。 

ChildWindow的默认模板示例:

 

代码
   
     
< ControlTemplate TargetType ="controls:ChildWindow" >
< Grid x:Name ="Root" >
< Grid x:Name ="Overlay" HorizontalAlignment ="Stretch" VerticalAlignment ="Top" Margin ="0" Background =" {TemplateBinding OverlayBrush} " Opacity =" {TemplateBinding OverlayOpacity} " />
< Grid x:Name ="ContentRoot" HorizontalAlignment =" {TemplateBinding HorizontalAlignment} " VerticalAlignment =" {TemplateBinding VerticalAlignment} " RenderTransformOrigin ="0.5,0.5" Height =" {TemplateBinding Height} " Width =" {TemplateBinding Width} " >
< Border CornerRadius ="1.5" Margin ="1" >
< Grid >
< Grid.RowDefinitions >
< RowDefinition Height ="Auto" />
< RowDefinition />
</ Grid.RowDefinitions >
< Border x:Name ="Chrome" Width ="Auto" BorderBrush ="#FFFFFFFF" BorderThickness ="0,0,0,1" >
< Grid Height ="Auto" Width ="Auto" >
< Grid.ColumnDefinitions >
< ColumnDefinition />
< ColumnDefinition Width ="30" />
</ Grid.ColumnDefinitions >
< ContentControl Content =" {TemplateBinding Title} " IsTabStop ="False" FontWeight ="Bold" HorizontalAlignment ="Stretch" VerticalAlignment ="Center" Margin ="6,0,6,0" />
< Button x:Name ="CloseButton" Grid.Column ="1" IsTabStop ="False" HorizontalAlignment ="Center" VerticalAlignment ="Center" Width ="15" Height ="14" Style =" {StaticResource ButtonStyle} " />
</ Grid >
</ Border >
< Border Background =" {TemplateBinding Background} " Margin ="7" Grid.Row ="1" >
< ContentPresenter x:Name ="ContentPresenter" Content =" {TemplateBinding Content} " ContentTemplate =" {TemplateBinding ContentTemplate} " HorizontalAlignment =" {TemplateBinding HorizontalContentAlignment} " VerticalAlignment =" {TemplateBinding VerticalContentAlignment} " />
</ Border >
</ Grid >
</ Border >
</ Border >
</ Grid >
</ Grid >
</ ControlTemplate >

 

 

C#代码示例:

 

  
    
public void Show()
{
if ( this .ChildWindowPopup == null )
{
this .ChildWindowPopup = new Popup();
try
{
this .ChildWindowPopup.Child = this ;
}
catch (ArgumentException)
{
this .InteractionState = WindowInteractionState.NotResponding;
throw new InvalidOperationException(Resources.ChildWindow_InvalidOperation);
}
}
if (( this .ChildWindowPopup != null ) && (Application.Current.RootVisual != null ))
{
this .ChildWindowPopup.IsOpen = true ;
this ._dialogresult = null ;
}
if (RootVisual != null )
{
RootVisual.IsEnabled
= false ;
}
}

 

 

 

从模板和C#代码中,我们可以看到ChildWindow是用Popup来显示的,Overlay元素为背景,ContentRoot就是我们看到的弹出框的,Chrome作为弹出框头部。我们自定义的内容放在ContentPresenter中,掌握了ChildWindow的实现和模板后,我们就可以任意定制自己的弹出窗口了,改变弹出窗口的模板,并添加我们想要的功能。

 

默认的弹出框总是居中,如何改变弹出框位置呢? 我们可以在自定义的弹出框中重载OnApplyTemplate来给ContentRoot添加变换。

在这里我们还可以附加其他功能,如点击弹出框以外的部分时,让弹出框关闭等。示例代码如下。

 

  
    
public override void OnApplyTemplate()
{
base .OnApplyTemplate();


Overlay
= this .GetTemplateChild( " Overlay " ) as Panel;
if (Overlay != null )
{
Overlay.MouseLeftButtonDown
+= new MouseButtonEventHandler(Overlay_MouseLeftButtonDown);
}

TranslateTransform translate
= new TranslateTransform();
translate.X
= Left;
translate.Y
= Top;

TransformGroup renderTransform
= this .ContentRoot.RenderTransform as TransformGroup;
if (renderTransform != null )
{
renderTransform.Children.Add(translate);
}
else
{
this .ContentRoot.RenderTransform = translate;
}
}

你可能感兴趣的:(window)