#832 – Creating a Cursor File

If you want to use a custom cursor in your application, you can create a .cur (static) or .ani (animated) cursor file using a cursor creation application.  You can then embed the resulting cursor file in your application and load it at run-time.

One good example of a cursor creation application is the RealWorld Cursor Editor, available as freeware.

The RealWorld Editor allows creating a cursor from scratch or creating a cursor based on an image.  Below, we convert an image of Cyrano de Bergerac into a cursor that we can then use as the mouse pointer.

We load the image into the application.

832-001

We flip the image horizontally, rotate it so that the nose points up and to the left, and then erase everything but the face.

832-002

Finally, we use the Create mouse cursor command.

832-003

The hotspot is set to the tip of the nose.

832-004

832-005

832-006

 

Voila!

832-007

832-008

Advertisements

#831 – Embedding a Cursor in Your Project as a Resource

If you have a custom cursor that your application uses, you can load it at run-time from an external file.  But this requires that you distribute the cursor file with your application.  To avoid distributing the .cur file, you can embed this file into your project as a resource.

First, add the .cur file to your project and set its Build Action to Resource.

831-001

831-002

831-003

831-004

To load the cursor at run-time, you use the Application.GetResourceStream method, which returns a StreamResourceInfo object.  You can then use the Stream property of this object to create the cursor.  (You’ll need a using statement for the System.Windows.Resources namespace).

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            StreamResourceInfo sriCurs = Application.GetResourceStream(
                new Uri("captain-america-arrow.cur", UriKind.Relative));

            this.Cursor = new Cursor(sriCurs.Stream);
        }

831-005

#830 – Loading a Cursor from a File

You can set a cursor in your application to a cursor that you load from a .cur or .ani file.  The constructor for the System.Windows.Input.Cursor class accepts either a filename or a stream.  If you use a filename, you should use the full path to your cursor file.

In the example below, we set the cursor for the parent window to one of two different cursors, depending on which button we click.

    <StackPanel>
        <Button Content="Steve Rogers" Margin="10"
               Click="Button_Click_1"/>
        <Button Content="Peggy Carter" Margin="10"
                Click="Button_Click_2"/>
    </StackPanel>

 

        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            string fullPath = Path.Combine(Environment.CurrentDirectory, "captain-america-arrow.cur");
            this.Cursor = new Cursor(fullPath);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            string fullPath = Path.Combine(Environment.CurrentDirectory, "captain-america-shield.ani");
            this.Cursor = new Cursor(fullPath);
        }

830-001
830-002

#829 – Setting an Application-Wide Cursor from Code

You can use the Cursors property of a FrameworkElement to set the cursor that the user sees when moving the mouse over that element.  This cursor will also be used on descendant elements of the element where you set the cursor.

You can also set the cursor from code.  You could just set the Cursor property of an individual element in code.  But you can also set the static Mouse.OverrideCursor property, indicating a cursor that should be used throughout the entire application.  This will override any Cursor properties of individual elements.

    <StackPanel>
        <Label Content="Ad eundum quo nemo ante iit"
               Background="LightCoral"
               Cursor="Hand"/>
        <Label Content="Noli habere bovis, vir"
               Background="DarkSeaGreen"/>
        <Button Content="Ventilabis Me"
                Click="btnClick"
                HorizontalAlignment="Center"/>
    </StackPanel>

 

        private void btnClick(object sender, RoutedEventArgs e)
        {
            Mouse.OverrideCursor = Cursors.AppStarting;
        }

829-001
829-002

#828 – ListView and GridView Data Binding Example

ListView control contains a collection of items that you can view in different ways.  The current view can be set using the View property, which can be set to an instance of a GridView.  A GridView is an object that can display the data in columns.

Below is a complete example of a bound ListView that uses a GridView to display its items.  The ListView is bound to a collection and the GridView contains GridViewColumn instances, each of which is bound to a property of the items contained in the collection.

    <StackPanel>
        <Label Content="Ad eundum quo nemo ante iit"
               Margin="5"
               Background="LightCoral"/>
        <ListView ItemsSource="{Binding Guys}">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Name}"
                                    Header="Guy"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Age}"
                                    Header="Age"/>
                </GridView>
            </ListView.View>
        </ListView>
    </StackPanel>

The code-behind for the top-level Window sets the data context and creates the collection.

    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public ObservableCollection<Person> Guys { get; protected set; }

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

            Guys = new ObservableCollection<Person>();
            Guys.Add(new Person("Julius Caesar", 40));
            Guys.Add(new Person("Pompeius Magnus", 46));
            Guys.Add(new Person("Marcus Crassus", 55));
            RaisePropertyChanged("Guys");
        }

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

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

For completeness, here is the implementation of the Person class.

    public class Person :  INotifyPropertyChanged
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

828-001

#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