#477 – Default ZIndex Value for Child Elements of a Canvas

You can set the Canvas.ZIndex attached property for a child element of the Canvas panel, to dictate the overlap behavior of child elements.  Elements with a higher ZIndex value will appear on top of elements with a lower value.

By default, all child elements of a Canvas have a ZIndex value of 0.  In this case, the Canvas lays out the child elements in the order that they exist in the Children collection (the same order in which they appear in XAML), with elements occurring later in the collection layering on top of elements that occur earlier in the collection.

More generally, any time that two elements have the same value for ZIndex, they are layered in the order in which the appear in the Children collection.


			

#476 – Set ZIndex Values for Child Elements of Canvas

By default, child elements of a Canvas panel will be arranged in the order that they appear in a XAML file, with later elements appearing on top of earlier elements.

You can override this behavior by specifying explicit values for the Canvas.ZIndex attached property.  An element with a higher ZIndex value will appear on top of an element with a lower value.

        <Canvas Name="canv" Grid.Row="0">
            <Button Content="1 - Lft10,Top10" Canvas.Left="10" Canvas.Top="10" Canvas.ZIndex="4"/>
            <Button Content="2 - Rt10,Top10" Canvas.Right="10" Canvas.Top="15" Canvas.ZIndex="3"/>
            <Button Content="3 - Lft10,Bott10..." Canvas.Left="15" Canvas.Bottom="15" Canvas.ZIndex="2"/>
            <Button Content="4 - Rt10,Bott10" Canvas.Right="10" Canvas.Bottom="8"  Canvas.ZIndex="1"/>
        </Canvas>

#475 – Child Elements in Canvas Can Overlap

It’s possible for child elements of a Canvas to overlap each other, depending on their position.  In the example below, the Canvas contains four Button controls, each located relative to one of the four corners of the Canvas.  As the parent window is resized, it eventually gets small enough for the child elements to overlap.

When child elements in a Canvas overlap, their order is based on the order in which they were added to the Canvas.  If the elements were all specified in XAML, the first elements listed will be at the bottom of overlapped elements and the last elements will be at the top.

    <Canvas>
        <Button Content="1 - Lft10,Top10" Canvas.Left="10" Canvas.Top="10"/>
        <Button Content="2 - Rt10,Top10" Canvas.Right="10" Canvas.Top="15"/>
        <Button Content="3 - Lft10,Bott10..." Canvas.Left="15" Canvas.Bottom="15"/>
        <Button Content="4 - Rt10,Bott10" Canvas.Right="10" Canvas.Bottom="8"/>
    </Canvas>

#474 – Hiding a ComboBox Selection Highlight When the Mouse Moves off Item

By default, when you have a ComboBox open in WPF, a highlight is shown as you hover over different items in the ComboBox.

The last item that you hovered over with the mouse will remain selected even if you move the mouse off of the ComboBox.

If you’d rather have an item selected in the ComboBox only when you hover over it, you can modify the ItemContainerStyle for the ComboBox.

You can use Blend to make a copy of the existing template and then make changes to the copy.  In the template, you’ll find a trigger that sets the background of the ComboBoxItem when the IsHighlighted property is true.  You can change this to a MultiTrigger that also checks IsMouseOver.

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsHighlighted" Value="true"/>
        <Condition Property="IsMouseOver" Value="true"/>
    </MultiTrigger.Conditions>
    <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</MultiTrigger>

#473 – Positioning Child Elements in a Canvas

Child elements are position in a Canvas panel by specifying the location of the child element in WPF units.

You can position all elements by specifying values for Left and Top properties only.  This will position each element relative to the upper left corner of the container.

These child elements will then retain the same position from the upper left corner of the container as it is resized.

You can specify a child element’s position relative to any of the four corners of the container, depending on which two of the four positioning properties you specify.  Child elements will then retain their position relative to that corner as the container is resized.

  • Left/Top – upper left corner
  • Right/Top – upper right corner
  • Right/Bottom – lower right corner
  • Left/Bottom – lower bottom corner
    <Canvas>
        <Button Content="Left=10,Top=10" Canvas.Left="10" Canvas.Top="10"/>
        <Button Content="Right=10,Top=10" Canvas.Right="10" Canvas.Top="10"/>
        <Button Content="Right=10,Bottom=10" Canvas.Right="10" Canvas.Bottom="10"/>
        <Button Content="Left=10,Bottom=10" Canvas.Left="10" Canvas.Bottom="10"/>
    </Canvas>


#472 – UniformGrid Defaults to Being Square

You typically set the number of rows and columns for a UniformGrid using the Rows and Columns properties.  You can also omit these properties and the UniformGrid will set the number of rows and columns based on the number of child elements.

The UniformGrid will attempt to create a square layout by automatically setting the number of rows and columns as listed below:

  • 1 element – 1 row, 1 column
  • 2-4 elements – 2 rows, 2 columns
  • 5-9 elements – 3 rows, 3 columns
  • 10-16 elements – 4 rows, 4 columns
  • Etc.

Notice that the UniformGrid in this situation will always have the same number of rows as columns.

    <UniformGrid>   <!-- No Rows/Columns specified -->
        <Label Content="1st" Background="AliceBlue" />
        <!-- Etc -->
    </UniformGrid>
</UniformGrid>





#471 – How FlowDirection Works with the Image Element

Unlike other elements, the Image control will not inherit it’s parent’s value of FlowControl.  However, you can explicitly set FlowControl for an Image to RightToLeft, which will flip the image horizontally.

    <StackPanel Orientation="Horizontal">
        <Image Source="Images\BestYears.jpg" Margin="5"/>
        <Image Source="Images\BestYears.jpg" Margin="5" FlowDirection="RightToLeft"/>
    </StackPanel>