5 Tricks you should know in WPF – PART 2

1. TextBlock is not just for Text

We all know that TextBlock is an UI control, which will carry a piece of text. But actually MSDN explains it in a bit different way.

Provides a lightweight control for displaying small amounts of flow content.

Flow Content !!!, which not means only text. Lets look at the power of TextBlock. TextBlock can carry any UIElement. It may be an image, path or even a button.

<TextBlock>
    TextBlock can carry a 
    <Button Content="Button"/>
    and even a 
    <CheckBox Content="CheckBox" IsChecked="True"/> .
    That is awesome. 
    <Image Source="smiley.png" />
</TextBlock>

The above code will give the following output.

textblock

2. SharedSizeScope

Grid is the most flexible panel, where elements can arranged in rows and columns manner. Some situation, there might be multiple grids with same row and column sizing. So if there is any design change (design time or run time), we have to change the size in every grid. But SharedSizeScope feature will provide a flexibility, that multiple grids can share the size information. So if one grid affected by size change in its row/columns, others will get the change automatically.

Rows and Columns having the same group name will share the size information.

    <Grid Grid.IsSharedSizeScope="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid x:Name="Grid1" Margin="10" ShowGridLines="True">
            <Grid.RowDefinitions>
                <RowDefinition Height="30" SharedSizeGroup="HeaderRow"/>
                <RowDefinition Height="120" SharedSizeGroup="ContentRow"/>
            </Grid.RowDefinitions>
            <Rectangle Fill="LightCoral"/>
            <Rectangle Fill="LightBlue"
                       Grid.Row="1"/>
        </Grid>
        <Grid x:Name="Grid2" Margin="10" ShowGridLines="True" Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition SharedSizeGroup="HeaderRow"/>
                <RowDefinition SharedSizeGroup="ContentRow"/>
            </Grid.RowDefinitions>
            <Rectangle Fill="LightCoral" />
            <Rectangle Fill="LightBlue"
                       Grid.Row="1" />
        </Grid>
    </Grid>

The above code will produce the following output,

window
Note : SharedSizeScope will not work for Star Sizing. Star will be considered as auto.

3. x:References in XAML

The markup will directly refer an instance which is declared elsewhere in the XAML. the reference will be identified by the x:Name.

<StackPanel>
    <Label Content="_Name" Target="{x:Reference txtName}"/>
    <TextBox x:Name="txtName"/>
</StackPanel>

In the above code, the TextBox with name txtName will become the target of the Label. This can also be achieved using ElementName binding as below,

<StackPanel>
    <Label Content="_Name" Target="{Binding ElementName=txtName}"/>
    <TextBox x:Name="txtName"/>
</StackPanel>

Note : Anybody confused about Target property of Label? No Problem !!! The property referes to the element which will get focus, when user presses the label’s access key. Here the access key is “N”.

Label

4. FallBackValue and TargetNullValue

When the binding is unable to return a valid value, Fallback value will be used as the result. A binding can fail for following reasons,

1. The path to the binding not resolved.
2. The Value Converter (if any), not able to convert the value.
3. The resulting value is not valid for target property.

Whenever the binding fails, DependencyProperty.UnsetValue will be return as the result. Fallback value will replace the UnsetValue. The following code will show “Name cannot be shown”, if binding fails.

<TextBlock Text="{Binding Name, FallbackValue='Name cannot be shown'}"/>

TargetNullValue will be considered when the source value is NULL. The below code will show “Name cannot be show”, when the Name property is NULL.

<TextBlock Text="{Binding Name, TargetNullValue='Name cannot be shown'}"/>

5. Priority Binding

PriorityBinding works with list of Bindings. The value of the property will be resolved in priority basis. If the highest priority binding returns the value successfully, the other bindings will not be processed. If the highest priority binding took time to resolve the value, then the second highest priority binding will be processed and return the value until the highest priority binding done resolving the value.

  <TextBlock>
    <TextBlock.Text>
      <PriorityBinding FallbackValue="defaultvalue">
        <Binding Path="SlowestValue" IsAsync="True"/>
        <Binding Path="SlowerValue" IsAsync="True"/>
        <Binding Path="FastValue" />
      </PriorityBinding>
    </TextBlock.Text>
  </TextBlock>

When the binding engine processes the Binding objects, it starts with the first Binding, which is bound to the SlowestValue property. When this Binding is processed, it does not return a value successfully if it going to take long time, so the next Binding element is processed. The next Binding does not return a value successfully if that going to take a few time. The binding engine then moves onto the next Binding element, which is bound to the FastValue property. This Binding returns the value “Fast Value”. The TextBlock now displays the value “Fast Value”.

Leave a comment

Up ↑