Sunday, April 3, 2011

Creating a common window look in WPF

How would I create a common window look in WPF? I'm not talking about just styling the window, I'm mean having a window that has a border, grid, and some other things in it.

Thanks.

From stackoverflow
  • You can create a ControlTemplate for the window. Here is a pretty basic example that has some controls and triggers. You can easily add more elements to make it fit your needs.

       <ControlTemplate x:Key="MyWindowTemplate" TargetType="{x:Type Window}">
          <Border x:Name="WindowBorder" Style="{DynamicResource WindowBorderStyle}">
             <Grid>
                <Border Margin="4,4,4,4" Padding="0,0,0,0" x:Name="MarginBorder">
                   <AdornerDecorator>
                      <ContentPresenter/>
                   </AdornerDecorator>
                </Border>
                <ResizeGrip Visibility="Collapsed" IsTabStop="false" HorizontalAlignment="Right" x:Name="WindowResizeGrip" 
                        VerticalAlignment="Bottom" />
             </Grid>
          </Border>
          <ControlTemplate.Triggers>
             <MultiTrigger>
                <MultiTrigger.Conditions>
                   <Condition Property="ResizeMode" Value="CanResizeWithGrip"/>
                   <Condition Property="WindowState" Value="Normal"/>
                </MultiTrigger.Conditions>
                <Setter Property="Visibility" TargetName="WindowResizeGrip" Value="Visible"/>
                <Setter Property="Margin" TargetName="MarginBorder" Value="4,4,4,20" />
             </MultiTrigger>
             <Trigger Property="WindowState" Value="Maximized">
                <Setter Property="CornerRadius" TargetName="WindowBorder" Value="0,0,0,0"/>
             </Trigger>
          </ControlTemplate.Triggers>
       </ControlTemplate>
    

    You can use this ControlTemplate by setting the template property of the Window:

       Template="{StaticResource MyWindowTemplate}"
    

    You will want to use this in conjunction with a style like this:

       <Style x:Key="MyWindowStyle" TargetType="{x:Type Window}">
          <Setter Property="AllowsTransparency" Value="False" />
          <Setter Property="WindowStyle" Value="SingleBorderWindow" />
          <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
          <Setter Property="Background" Value="Transparent" />
          <Setter Property="ShowInTaskbar" Value="False" />
          <Setter Property="Template">
             <Setter.Value>
                <ControlTemplate TargetType="{x:Type Window}">
                   <Border>
                      <AdornerDecorator>
                         <ContentPresenter/>
                      </AdornerDecorator>
                   </Border>
                </ControlTemplate>
             </Setter.Value>
          </Setter>
       </Style>
    

    And set the style on your Window like this:

    Style="{StaticResource MyWindowStyle}"
    
    Josh Close : This works great. The only problem I have now is that I have some events in the ControlTemplate code. If I want all windows to use the template, then I need to put the resource in a different file. When I do that, the events don't work anymore.
  • What I ended up doing was creating a base class that created the UI code that I wanted in every window. This allows me to set events for controls and have the event subscription in the base class. If there is a better way of doing this, like using xaml, I'd like to know.

    public WindowBase()
    {
        Initialized += WindowBase_Initialized;
    }
    
    private void WindowBase_Initialized( object sender, EventArgs e )
    {
        Border border = new Border();
        border.SetResourceReference( Control.StyleProperty, "WindowBorder" );
    
        border.Child = new ContentPresenter { Content = this.Content};
    
        this.Content = border;
    }
    

0 comments:

Post a Comment