views:

77

answers:

3

Just being new to WPF I"m not sure what control or approach would be best for this requirement, for a WPF application.

  • I want to present a summary table of information, but the user should be able to decide to view the information based on either: "All Time", Month, Week or Day.
  • I'd like to visually have the selection of the option appear at the top of this section and have it appear as a TabControl
  • I'm not sure however whether TabControl is the best choice re repeating the table for each Tab Item
  • So overall functionally what would work is just radio buttons across the top, however what I want visually is a TabControl look

What would be the best way to achieve the TabControl look but with a programming approach for which I don't have to repeat things in each Tab Item?

For example, would I use a TabControl and then a WPF template to do the equivalent of an include in each Tab Item but with a different input parameter? (haven't used WPF templates before)

Thanks

+5  A: 

Since you want the behavior of a group of RadioButtons and you want the visual appearance of a TabItem, you should use RadioButton controls and style them such that they look like TabItem controls. Here is a very simple example:

alt text

<Window x:Class="TabTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="{x:Type RadioButton}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <Border x:Name="tabBorder" BorderThickness="1" BorderBrush="Black"
                                Margin="0,0,-4,0"
                                CornerRadius="2,12,0,0"
                                Background="White"
                                SnapsToDevicePixels="True">
                            <ContentPresenter                                 
                                Margin="12,2,12,2"
                                VerticalAlignment="Center"
                                HorizontalAlignment="Left"
                                RecognizesAccessKey="True"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="tabBorder" Property="Background" Value="LightBlue" />
                                <Setter TargetName="tabBorder" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Grid Margin="4">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,0,0,-1" Panel.ZIndex="1">
            <RadioButton>All Time</RadioButton>
            <RadioButton IsChecked="True">Month</RadioButton>
            <RadioButton>Week</RadioButton>
            <RadioButton>Day</RadioButton>
        </StackPanel>
        <Border Grid.Row="1" Background="LightBlue" 
                BorderThickness="1" BorderBrush="Black"
                SnapsToDevicePixels="True">
            <Button Margin="10" Grid.Row="1">This is a test</Button>
        </Border>
    </Grid>
</Window>

In this example, the Button is the place where you would put your summary table.

fmunkert
Greg
+2  A: 

Greg, I suppose, grouping grid would be the most ideal control of your requirement. Either you can customize the datagrid as explained in the following article. But this would take more time to get things right.

http://blog.smoura.com/wpf-toolkit-datagrid-part-iv-templatecolumns-and-row-grouping/

or else you could make use of commercial WPF Grid grouping control which would match you requirement.

Karthik
A: 

What would be the best way to achieve the TabControl look but with a programming approach for which I don't have to repeat things in each Tab Item?

Use a TabControl. Have each TabItem contain a CollectionViewSource based on the same underlying collection of data, but with a different filter. Use a DataTemplate to present the CollectionViewSource.

Filtering requires some kind of code-behind, but here's a XAML-only demo that does sorting:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase">
  <Page.Resources>
    <XmlDataProvider x:Key="Data">
      <x:XData>
        <Data xmlns="">
          <Item Date="2010-01-01" Value="January"/>
          <Item Date="2010-02-01" Value="February"/>
          <Item Date="2010-03-01" Value="March"/>
          <Item Date="2010-04-01" Value="April"/>
          <Item Date="2010-05-01" Value="May"/>
          <Item Date="2010-06-01" Value="June"/>
          <Item Date="2010-07-01" Value="July"/>
          <Item Date="2010-08-01" Value="August"/>
          <Item Date="2010-09-01" Value="September"/>
        </Data>
      </x:XData>
    </XmlDataProvider>
    <CollectionViewSource x:Key="ByDate" Source="{Binding Source={StaticResource Data}, XPath=Data/Item}">
      <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="@Date"/>
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
    <CollectionViewSource x:Key="ByValue" Source="{Binding Source={StaticResource Data}, XPath=Data/Item}">
      <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="@Value"/>
      </CollectionViewSource.SortDescriptions>
    </CollectionViewSource>
    <DataTemplate DataType="{x:Type CollectionViewSource}">
      <Border Margin="5" BorderBrush="DodgerBlue" BorderThickness="1" CornerRadius="4">
        <DockPanel Margin="5">
          <Label DockPanel.Dock="Top">This is here to show how you can make the layout of your TabItems complex without repeating yourself.</Label>
          <ListBox DockPanel.Dock="Top" x:Name="Items" ItemsSource="{Binding}" DisplayMemberPath="@Value" SelectedValuePath="@Value"/>
          <DockPanel>
            <Label>Selected item: </Label>
            <Label Content="{Binding ElementName=Items, Path=SelectedValue}"/>
          </DockPanel>
        </DockPanel>
      </Border>
    </DataTemplate>
  </Page.Resources>
  <Grid>  
    <TabControl>
       <TabItem Header="By date" Content="{StaticResource ByDate}"/>
       <TabItem Header="By value" Content="{StaticResource ByValue}"/>
    </TabControl>
  </Grid>
</Page>
Robert Rossney