User Tools

Site Tools


notes:uwp:contentcontrol

Content in XAML

ContentControl

A partial control hierarchy for the ContentControl defined in Windows.UI.Xaml.Controls:

Object
 └─DependencyObject
   └─UIElement 
     └─FrameworkElement 
       └─Control
         └─ContentControl
           ├─ButtonBase
           │ ├─Button
           │ ├─HyperlinkButton
           │ ├─RepeatButton
           │ └─ToggleButton
           │   ├─CheckBox
           │   └─RadioButton
           ├─SelectorItem (non-instantiable)
           │ ├─ComboBoxItem
           │ ├─FlipViewItem
           │ ├─GridViewItem
           │ ├─ListBoxItem
           │ └─ListViewItem
           ├─ScrollViewer
           ├─AppBar
           │ └─CommandBar
           └─SettingsFlyout

The ContentControl exhibits the following behaviour:

  • The ContentControl is stretched to fill the available space but it does not provide this space to the child. Unless the child has a fixed height and width, it will not be given any size to expand into:
<Grid>
    <!-- nothing is rendered -->
    <ContentControl HorizontalAlignment="Stretch" 
                    VerticalAlignment="Stretch">
        <Rectangle Fill="Green" />
    </ContentControl>
</Grid>
  • When HorizontalContentAlignment and VerticalContentAlignment are set to Stretch, the child is given the entire space to expand into:
<Grid>
    <!-- a green rectangle is rendered -->
    <ContentControl HorizontalAlignment="Stretch" 
                    VerticalAlignment="Stretch">
                    HorizontalContentAlignment="Stretch"
                    VerticalContentAlignment="Stretch"
        <Rectangle Fill="Green" />
    </ContentControl>
</Grid>

The ContentControl can be used to set some visual aspects of a child control such as FontSize:

<ContentControl FontSize="25">
    <!-- StackPanel does not have the FontSize property -->
    <StackPanel>
        <TextBlock Text="Test1" />
        <TextBlock Text="Test2" />
        <TextBlock Text="Test3" />
    </StackPanel>
</ContentControl>

The ContentControl can serve as a ContentPresenter in a control template:

<Button Content="Test" Background="Bisque">
    <Button.Template>
        <ControlTemplate TargetType="Button">
            <Border Width="200" Height="100" CornerRadius="20"
                    Background="{TemplateBinding Background}">
                <ContentControl Content="{TemplateBinding Content}"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center" />
            </Border>
        </ControlTemplate>
    </Button.Template>
</Button>

The ContentControl provides the ContentTemplate property to provide a template for its content:

<Page ...>
    <Page.Resources>
        <DataTemplate x:Key="CustomerTemplate">
            ...  
        </DataTemplate>
    </Page.Resources>
 
    <Grid>
        <ContentControl Content="{Binding Customer}" ContentTemplate="{StaticResource CustomerTemplate}" />
    </Grid>
</Page>

Content Property

The following two code snippets are equivalent:

<!-- Snippet #1 -->
<Page ...>
    <Grid ...>
        <TextBlock ... />
        <TextBlock ... />
        <TextBlock ... />
    </Grid>
</Page>
 
<!-- Snippet #2 -->
<Page ...>
    <Page.Content>
        <Grid ...>
            <Grid.Children>
                <TextBlock ... />
                <TextBlock ... />
                <TextBlock ... />
            </Grid.Children>
        </Grid>
    </Page.Content>
</Page>

The reason we can omit the content properties Page.Content and Grid.Children in the snippet #1 is that all classes referenced in XAML are allowed to have one content property. For this property, property tags are not required.

The content property is specified using the ContentPropertyAttribute located in the Windows.UI.Xaml.Markup namespace:

[ContentProperty(Name="Children")]
public class Panel : FrameworkElement { ... }
 
[ContentProperty(Name="Content")]
public class UserControl : Control { ... }

In the following code snippet we can omit not only the content property LinearGradientBrush.GradientStops but also the collection object GradientStopCollection:

<TextBlock>
    <TextBlock.Foreground ...>
        <LinearGradientBrush ...>
            <LinearGradientBrush.GradientStops>
                <GradientStopCollection>
                    <GradientStop ...>
                    <GradientStop ...>
                </GradientStopCollection>
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush ...>
    </TextBlock.Foreground ...>
</TextBlock>                  

ScrollViewer

  • ScrollViewer is a wrapper that provides scrolling capability for controls such as StackPanel.
  • Placing a list control in ScrollViewer breaks virtualization of the list control.
  • An advantage of the ScrollViewer is the built-in support for touch and zoom.

The ScrollViewer properties:

  • Content - the content that we want to scroll (an image, a panel, etc.)
  • ZoomMode - enables and disables zoom-in/zoom-out capability
  • VerticalScrollBarVisibility / HorizontalScrollBarVisibility
    • Visible - The scrollbar appears whenever the ScrollViewer has focus.
    • Auto - The same as Visible if the content requires scrolling; Disabled otherwise.
    • Hidden - The scrollbar is hidden. It is still possible to scroll using touch or keyboard but not the mouse.
    • Disabled - The scrollbar does not exist. It is not possible to scroll at all. The content occupies the visible area in the parent element.
  • VerticalScrollMode / HorizontalScrollMode
    • Disabled - Scrolling is disabled.
    • Enabled - Scrolling is enabled.
    • Auto - Scrolling is enabled but behavior uses a “rails” manipulation mode.

Grid vs. ScrollViewer:

  • Grid tells the child elements how much space they have.
  • ScrollViewer stretches to contain all child elements.
  • When the ScrollViewer is placed in a Grid, it occupies the available area by default.

The properties of the ScrollViewer relevant for zooming:

  • ZoomMode - Indicates if zooming is available.
  • ZoomFactor - Specifies the scaling factor. The default value is 1.0 i.e. no scaling. Use the ZoomToFactor method to change the value of this property at runtime.
  • MinZoomFactor and MaxZoomFactor - Specify the minimum and maximum runtime values for ZoomFactor.
  • IsZoomChainingEnabled - Specifies whether zoom chaining is enabled from the child to its parent. Zoom chaining controls whether the zooming action carried out by the user on a child element should be available on the parent ScrollViewer control.
  • IsZoomInertiaEnabled - Specifies whether the zoom actions should include inertia in their behavior and value.

Snap-points can be set to aid users in getting to key locations in the content. There are two different types of snap-points:

  • Mandatory snap-points (Mandatory and MandatorySingle) - When the user lifts their finger, the content is always smoothly animated to a snap-point.
  • Proximity snap-points (Optional and OptionalSingle) - When the user lifts their finger, the content is animated to a snap-point only if the content is in close proximity of the snap-point.

Some of the ScrollViewer properties can be accessed as attached properties:

  • ScrollViewer.HorizontalScrollMode (e.g. Enabled)
  • ScrollViewer.HorizontalScrollBarVisibility (e.g. Auto)
  • ScrollViewer.VerticalScrollMode (e.g. Disabled)
  • ScrollViewer.VerticalScrollBarVisibility (e.g. Disabled)

Example: A StackPanel wrapped in a ScrollViewer:

<ScrollViewer HorizontalAlignment="Center">
    <StackPanel>
        <Rectangle Fill="Blue" Width="180" Height="180" Margin="8" />
        <Rectangle Fill="Green" Width="180" Height="180" Margin="8" />
        <Rectangle Fill="Yellow" Width="180" Height="180" Margin="8" />
        <Rectangle Fill="Red" Width="180" Height="180" Margin="8" />
        <Rectangle Fill="Magenta" Width="180" Height="180" Margin="8" />
    </StackPanel>
</ScrollViewer>

The following ScrollViewer won't have the ability to scroll because the parent StackPanel reserves infinite space for its children:

<StackPanel>
    <ScrollViewer>
        ...
    </ScrollViewer>
</StackPanel>

Some item controls such as ListView have an internal ScrollViewer. Use attached properties to modify the internal ScrollViewer:

<ListView ScrollViewer.VerticalScrollBarVisibility="Auto">
...
</ListView>
notes/uwp/contentcontrol.txt · Last modified: 2017/02/15 by admin