Compact CheckBox Sample


I was creating a view of an object that had a bunch of boolean properties, but I wanted to keep the visual representation small.  So I created a look for a compact CheckBox that I liked enough to post.

As an example scenario, say I’m visualizing a the attributes of a file (hidden, system, archive, and read-only).  I could do it with a TextBlock and some CheckBoxes easy enough, to create a look like this:

 


image


 


… but I want it more compact.  I want just a letter for each attribute, and I just want the letter to change when it’s checked.  That got me this:


 


image


 


Here, the light gray italicized boxes are un-checked, and the un-italicized black letters with a gray background are checked.  (So before capturing this screenshot, I had checked the read-only and archive bits on the “readme.txt” file.)   This image doesn’t show it, but there’s also a tooltip for each CheckBox that shows the full name of the attribute.


 


Here’s the ControlTemplate for the CheckBox:


 


<ControlTemplate TargetType=CheckBox>


  <Border BorderThickness={TemplateBinding BorderThickness}


          BorderBrush=Gray Background=LightGray Padding=2


          Name=_border >


    <Grid Margin=1>


      <TextBlock Text={TemplateBinding Content}


                 FontStyle=Italic


                 Foreground=LightGray/>


      <TextBlock Text={TemplateBinding Content}


                 Name=_checkedTextBlock />


    </Grid>


  </Border>


 


  <ControlTemplate.Triggers>


    <Trigger Property=IsChecked Value=False>


      <Setter TargetName=_checkedTextBlock


              Property=Opacity Value=0 />


      <Setter TargetName=_border


              Property=Background Value=Transparent />


    </Trigger>


  </ControlTemplate.Triggers>


</ControlTemplate>


 


The interesting thing here is that I created two TextBlocks to show the content of the CheckBox (e.g. the “R” for the read-only attribute CheckBox).  The first one shows the content in “unchecked” form, and the second one shows it in “checked” form.  The Trigger then picks which one shows up.  I had started with a single TextBlock, and had the Trigger set the FontStyle and Foreground.  The problem with this is that the italicized text is slightly wider than the normal text, and that caused the checkboxes to jiggle a little bit when you click on them.  There’s probably other ways to solve this, but a simple solution was to have both TextBlocks there and taking up space in layout, and then let the Trigger decide which one wins for render.


 


And here’s a full template with sample usage, again with some of the more interesting parts highlighted.  (I changed the trigger so that instead of a Setter to update the Background when IsChecked changes, it animates the change.)


 


<Page


  xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation


  xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml>


 


  <Grid>


   


    <Grid.ColumnDefinitions>


      <ColumnDefinition Width=Auto />


    </Grid.ColumnDefinitions>


 


    <Grid.Resources>


     


      <!– Implicit style to be applied to all CheckBoxs in this Window


           (this sets the new template) –>


 


      <Style TargetType=CheckBox>


       


        <Setter Property=BorderThickness Value=1,0,0,0 />


        <Setter Property=Template>


          <Setter.Value>


           


            <ControlTemplate TargetType=CheckBox>


              <Border BorderThickness={TemplateBinding BorderThickness}


                      BorderBrush=Gray Background=LightGray Padding=2


                      Name=_border >


                <Grid Margin=1>


                  <TextBlock Text={TemplateBinding Content}


                             FontStyle=Italic


                             Foreground=LightGray/>


                  <TextBlock Text={TemplateBinding Content}


                             Name=_checkedTextBlock />


                </Grid>


              </Border>


 


              <ControlTemplate.Triggers>


                <Trigger Property=IsChecked Value=False>


                 


                  <Setter TargetName=_checkedTextBlock


                          Property=Opacity Value=0 />


                 


                  <!– Instead of a Setter to update the background color,


                       use Trigger.EnterActions/ExitActions to animate it


                  <Setter TargetName=”_border”


                          Property=”Background” Value=”Transparent” /> –>


 


                  <Trigger.EnterActions>


                    <BeginStoryboard>


                      <Storyboard TargetName=_border TargetProperty=Background.Color>


                        <ColorAnimation Duration=0:0:0.5 To=Transparent />


                      </Storyboard>


                    </BeginStoryboard>


                  </Trigger.EnterActions>


 


                  <Trigger.ExitActions>


                    <BeginStoryboard>


                      <Storyboard TargetName=_border TargetProperty=Background.Color>


                        <ColorAnimation Duration=0:0:0.5 />


                      </Storyboard>


                    </BeginStoryboard>


                  </Trigger.ExitActions>


                 


                </Trigger>


              </ControlTemplate.Triggers>


            </ControlTemplate>


           


          </Setter.Value>


        </Setter>


      </Style>


 


      <!– This DataTemplate is used to display attributes for one file –>


     


      <DataTemplate x:Key=FileTemplate>


        <Border BorderThickness=1 BorderBrush=Black


                Margin=4 CornerRadius=5,5,0,0 Background=#FF83AFEA>


          <StackPanel >


           


            <!– Show the file name –>


            <Border Padding=2,2,2,0 >


              <TextBlock Text={Binding XPath=@Name} HorizontalAlignment=Center Margin=1/>


            </Border>


 


            <!–  Show the attributes in a row –>


            <StackPanel Orientation=Horizontal Background=White>


              <CheckBox BorderThickness=0 ToolTip=Hidden


                        IsChecked={Binding XPath=@Hidden, Mode=TwoWay}>


                H</CheckBox>


              <CheckBox ToolTip=System


                        IsChecked={Binding XPath=@System, Mode=TwoWay}>


                S</CheckBox>


              <CheckBox ToolTip=Read only


                        IsChecked={Binding XPath=@ReadOnly, Mode=TwoWay}>


                R</CheckBox>


              <CheckBox BorderThickness=1,0,1,0 ToolTip=Archive


                        IsChecked={Binding XPath=@Archive, Mode=TwoWay}>


                A</CheckBox>


            </StackPanel>


           


          </StackPanel>


        </Border>


      </DataTemplate>


 


      <!– Sample data –>


 


      <XmlDataProvider x:Key=SampleData XPath=Files>


        <x:XData >


          <Files xmlns=“”>


            <File Name=autoexec.bat Archive=False System=False


                  ReadOnly=True Hidden=True />


            <File Name=readme.txt Archive=False System=True


                  ReadOnly=False Hidden=False />


          </Files>


        </x:XData>


      </XmlDataProvider>


 


    </Grid.Resources>


 


    <!– To test it out, show the sample data –>


   


    <ItemsControl ItemsSource={Binding XPath=File, Source={StaticResource SampleData}}


                  ItemTemplate={StaticResource FileTemplate} />


 


  </Grid>


</Page>