locked
GridSplitter in Style causes NullReferenceException RRS feed

  • Question

  • The following produces a NullReferenceException; however, if you remove the style and place the contents of the ControlTemplate in the window it works fine.

    Any ideas on what I'm doing wrong?

    Thanks

    Doesn't work:

    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" Height="300" Width="800">
     <Window.Style>
      <Style BasedOn="{StaticResource {x:Type Window}}"
          TargetType="Window"  >
       <Setter Property="Template">
        <Setter.Value>
         <ControlTemplate TargetType="{x:Type Window}">
          <Grid x:Name="grid" Background="LightBlue" >
           <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition/>
           </Grid.ColumnDefinitions>

           <TextBlock Grid.Column="0">Side 1</TextBlock>

           <GridSplitter Grid.Column="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Stretch"
                Background="Silver"
                ShowsPreview="True"
                Width="5"
                        />
           <TextBlock Grid.Column="2"><ContentPresenter /></TextBlock>
          </Grid>
         </ControlTemplate>
        </Setter.Value>
       </Setter>
      </Style>
     </Window.Style>
     <Grid>
        <TextBlock Text="Side 2" />
     </Grid>
    </Window>

    Works:

    <Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" Height="300" Width="800">
          <Grid x:Name="grid" Background="LightBlue" >
           <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"/>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition/>
           </Grid.ColumnDefinitions>

           <TextBlock Grid.Column="0">Side 1</TextBlock>

           <GridSplitter Grid.Column="1"
                HorizontalAlignment="Center"
                VerticalAlignment="Stretch"
                Background="Silver"
                ShowsPreview="True"
                Width="5"
                        />
           <TextBlock Grid.Column="2">Side 2</TextBlock>
          </Grid>
    </Window>

    Thursday, January 4, 2007 2:49 AM

Answers

  • GridSplitter needs an adorner layer above it somewhere in order to do the ShowsPreview feature.  Your second example uses the standard control template for Window, which looks essentially like this:

       <Border>
          <Grid>
             <AdornerDecorator>
                <ContentPresenter>
             </AdornerDecorator>
             <ResizeGrip/>
          </Grid>
       </Border>

    Your first example doesn't have an AdornerDecorator in the control template.  This makes the difference.  The GridSplitter looks for the AdornerDecorator, assumes that one was found, and ends up dereferencing null.  It should probably fail gracefully (i.e. no exception, or at least not NullReferenceException).

    Add an AdornerDecorator to your control template, and I bet it'll work.

    Thursday, January 4, 2007 7:16 PM

All replies

  • I am not sure what you are trying to do, if you want to add Grid to window you dont need to change the Template
    Thursday, January 4, 2007 10:14 AM
  • I'm working on an application framework and creating a standard set of common UI features (main window, about box, etc.).  I wanted others to be able to modify various things without having to drop into the code.  You can't inherit a window that is defined with XAML, so the style seemed to be the way to go.

    In any case, it seems like it should work, based on everything else I've been able to do with styles, so it just seemed odd.

    Thursday, January 4, 2007 1:51 PM
  • GridSplitter needs an adorner layer above it somewhere in order to do the ShowsPreview feature.  Your second example uses the standard control template for Window, which looks essentially like this:

       <Border>
          <Grid>
             <AdornerDecorator>
                <ContentPresenter>
             </AdornerDecorator>
             <ResizeGrip/>
          </Grid>
       </Border>

    Your first example doesn't have an AdornerDecorator in the control template.  This makes the difference.  The GridSplitter looks for the AdornerDecorator, assumes that one was found, and ends up dereferencing null.  It should probably fail gracefully (i.e. no exception, or at least not NullReferenceException).

    Add an AdornerDecorator to your control template, and I bet it'll work.

    Thursday, January 4, 2007 7:16 PM
  • yes, after adding adornerdecorator it works
    Thursday, January 4, 2007 7:27 PM
  • As lee d mentioned, adding the AdornerDecorator worked.  Thanks very much for taking the time to reply.

    WPF is amazing and the overall design very elegent, but I haven't hit a learning curve this steep since the first version of .NET.  Overall it has been much more fun than frustrating though.

    Thanks again. 

    Thursday, January 4, 2007 8:08 PM