#827 – Overriding the Cursor Properties of Child Elements

A child FrameworkElement can set a Cursor value that overrides the current Cursor value set by a parent (or ancestor) element.  This new Cursor value then applies in the element where it is set and any of its own child elements.

A parent/ancestor FrameworkElement can, however, force all child elements to use a particular cursor, by setting the ForceCursor property to true.  This overrides any Cursor property values that the child elements might set.

In the example below, the second Button sets its Cursor property to Hand, but this value is overridden because the parent StackPanel sets the ForceCursor property to true.

    <StackPanel Cursor="Hand" ForceCursor="True">
        <Label Content="Ad eundum quo nemo ante iit"
               Margin="5"
               Background="LightCoral"/>
        <Label Content="Noli habere bovis, vir"
               Margin="5"
               Background="DarkSeaGreen"/>
        <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="Center">
            <Button Content="Veni, Vidi"
                    Padding="10,5" Margin="10"/>
            <Button Content="Dormivi"
                    Cursor="Wait"
                    Padding="10,5" Margin="10"/>
        </StackPanel>
    </StackPanel>

827-001
827-002

#826 – Lower-Level Elements Can Have Different Cursor

Cursor set on a top-level FrameworkElement will also be used on all elements within the parent element’s logical tree.  All lower-level elements will show the same cursor when the user hovers over the element.

You can, however, set a Cursor on a top-level element and then set a different value for Cursor on the lower-level element.  The top-level Cursor will be used for all descendants of the top-level element except for the one that explicitly sets a different cursor.

    <StackPanel Cursor="Hand">
        <Label Content="Ad eundum quo nemo ante iit"
               Margin="5"
               Background="LightCoral"/>
        <Label Content="Noli habere bovis, vir"
               Margin="5"
               Background="DarkSeaGreen"/>
        <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="Center">
            <Button Content="Veni, Vidi"
                    Padding="10,5" Margin="10"/>
            <Button Content="Dormivi"
                    Cursor="Wait"
                    Padding="10,5" Margin="10"/>
        </StackPanel>
    </StackPanel>

826-001
826-002

#825 – Two Way Binding for a CheckBox

You can bind the IsChecked property of a CheckBox to a boolean variable, so that the variable will always reflect the current value of the CheckBox in the user interface.

You can also do two-way binding, where the boolean variable changes when the user toggles the CheckBox, but the CheckBox also toggles when the value of the variable changes.

        <Label Content="Things my dog can do:"/>
        <CheckBox Content="Sit" IsChecked="{Binding CanSit, Mode=TwoWay}"/>
        <CheckBox Content="Stay" IsChecked="{Binding CanStay, Mode=TwoWay}"/>
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
            <Button Content="Report State" Click="btnReportState_Click"
                    Margin="5"/>
            <Button Content="Change State" Click="btnChangeState_Click"
                    Margin="5"/>
        </StackPanel>

Code-behind:

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        private bool canSit;
        public bool CanSit
        {
            get { return canSit; }
            set
            {
                canSit = value;
                RaisePropertyChanged("CanSit");
            }
        }

        private bool canStay;
        public bool CanStay
        {
            get { return canStay; }
            set
            {
                canStay = value;
                RaisePropertyChanged("CanStay");
            }
        }

        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = this;
        }

        private void btnReportState_Click(object sender, RoutedEventArgs e)
        {
            MessageBox.Show(string.Format("Sit: {0}, Stay: {1}", CanSit, CanStay));
        }

        private void btnChangeState_Click(object sender, RoutedEventArgs e)
        {
            CanSit = CanSit ? false : true;
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propName)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

#824 – Setting a Cursor on a Top Level Element

When you set the Cursor property on a FrameworkElement, the cursor is displayed whenever you move the mouse pointer over that element.  This Cursor value will also apply to all descendants of the element.

In the example below, when we set the Cursor in the top-level Window, that cursor is used for all elements contained in the window.

Layout, within the Window:

    <StackPanel>
        <Label Content="Ad eundum quo nemo ante iit"
               Margin="5"
               Background="LightCoral"/>
        <Label Content="Noli habere bovis, vir"
               Margin="5"
               Background="DarkSeaGreen"/>
        <StackPanel Orientation="Horizontal"
                    HorizontalAlignment="Center">
            <Button Content="Veni, Vidi"
                    Padding="10,5" Margin="10"
                    Click="btnClick_Wait"/>
            <Button Content="Dormivi"
                    Padding="10,5" Margin="10"
                    Click="btnClick_StopWaiting"/>
        </StackPanel>
    </StackPanel>

Code-behind:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnClick_Wait(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.AppStarting;
        }

        private void btnClick_StopWaiting(object sender, RoutedEventArgs e)
        {
            this.Cursor = Cursors.Arrow;
        }
    }

824-001
824-002
824-003
824-004
824-005

#823 – Setting a Cursor from XAML

Every FrameworkElement has a Cursor property that you can set to an instance of a System.Windows.Input.Cursor object.  Typically, you’ll just set the property to one of the predefined cursors in the System.Windows.Input.Cursors class.

When you set the Cursor property on an element, you’re indicating which cursor should appear when a user moves the mouse over that element.

You can set the Cursor property in XAML or in code.  In either case, you can pick from one of the predefined cursors in System.Windows.Input.Cursors.  In the image below, Intellisense in Visual Studio shows a list of the available cursors when setting the Cursor property from XAML.

823-001

In the example below, we indicate that we want the Wait cursor displayed whenever we hover over the second label.

    <StackPanel>
        <Label Content="I'm just a label, you know?"
               Margin="5"
               Background="LightCoral"/>
        <Label Content="I'm waiting and waiting"
               Margin="5"
               Background="DarkSeaGreen"
               Cursor="Wait"/>
    </StackPanel>

823-002
823-003

#822 – Deciding which TextFormattingMode to Use

The TextOptions.TextFormattingMode property indicates whether fonts should be formatted using the standard WPF algorithm or the legacy GDI method for positioning the individual glyphs in the font.  The property can have one of the following values:

  • Ideal – Default value, formats text using the standard WPF method.  Glyph shapes are preserved, independent of their final position on the display
  • Display – Positions edges of glyphs on pixel boundaries.  Can result in clearer edges of text.

You should use the value of Ideal, except for the situations listed below.

Set TextFormattingMode to Display when all of the following is true:

  • The FontSize of the text is 14 or less  (small text)
  • Text is not being transformed (scaled, rotated, translated)
  • The exact shape of the glyphs is not critical (e.g. for some graphic design scenario)

#821 – Use TextFormattingMode to Make Text Look More Clear

WPF tries to retain the exact shape and style of each glyph in a font, no matter what size the font is being rendered at.  This means that as the text gets smaller, relative to the pixel density of the display, the edges of the glyphs may no longer occur at pixel boundaries.  When this happens, WPF will use anti-aliasing to render the edges of the glyphs in a different color.  This can lead to small text looking fuzzy, or having some odd color fragments along the edges of the letters.

To avoid fuzzy text at small sizes, you can set the TextOptions.TextFormattingMode property to Display (as opposed to the default value of Ideal).  This tells WPF to align the glyphs at pixel boundaries, which can lead to crisper/cleaner text.

        <TextBlock Text="WiWi WIWI HaHaHa (Ideal = Default)"
                   Margin="5"/>
        <TextBlock Text="WiWi WIWI HaHaHa (Display)"
                   TextOptions.TextFormattingMode="Display"
                   Margin="5"/>

821-001

#820 – Viewing Additional Font Properties in Windows Explorer

You can preview TrueType fonts in Windows Explorer and also get some basic properties about each font.  If you right-click on a font file, select Properties and then select the Details tab, you’ll see some basic information:

820-001

You can also download a Microsoft-provided tool, the OpenType Font File Properties Extension, to get even more information about each font.  You can download the tool from here.  (This tool will only work on 32-bit operating systems).

After installing the extension tool, the properties dialog for a font file will contain a number of additional tabs.

  • Embedding – Are you allowed to embed the font in your application?
  • CharSet/Unicode – What encoding method is used (e.g. Unicode)
  • Links – (optional) URL to font vendor
  • Description – General info on the font
  • License – license information
  • Version – font version
  • Hinting/Font Smoothing – point sizes for hinting/smoothing
  • Names – Font name, font family name, vendor, etc.
  • Features – Description from vendor

820-002

820-003

 

 

#819 – Previewing TrueType Fonts in Windows Explorer

You can view all installed fonts in Windows, using the Fonts applet.  You can also view font properties and preview arbitrary fonts using Windows Explorer.

For example, assume that you have a directory containing some TrueType (.ttf) fonts, which are not current installed.

You start by navigating to the folder containing the fonts.

819-001

You can set the view in Windows Explorer to one of the icon-based views (e.g. Large icons) to see a thumbnail-based preview of each font.

819-002

You can also turn on the Preview pane to see a preview of each font, as you select it.

819-003

Finally, as with the Fonts applet, you can double-click a font to open a preview of the font in a separate window.

819-004

#818 – Previewing Installed Fonts

You can easily get a preview of any of the fonts that are installed on your system.

You can see all installed fonts by opening the Fonts applet.  On Windows 8, click the Start button, type “fonts”, click on “Settings” in the search results and then double-click the Fonts icon.

818-001

 

This applet will show you a list of all fonts installed on your system, with each font displayed as a preview icon, or appearing as a stack of icons.

818-002

 

The icons that look like a stack indicate that there are multiple unique fonts for a particular font family.  Double-clicking on the stack shows you the individual fonts for that font family.

818-003

You can get a preview of any of the fonts by double-clicking the font (or right-clicking and selecting Preview).  A preview window will open, showing you a sample of the font.

818-004

 

Follow

Get every new post delivered to your Inbox.

Join 234 other followers