#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

Advertisement

#785 – Using the Visual Profiler Tool

Once you install the WPF Performance Suite, you can use the tool to help improve the performance of your application.

In addition to the Perforator tool, the Performance Suite includes the Visual Profiler tool, which is designed to help you profile your application at run-time.  Profiling involves monitoring your application at run-time to look at the performance aspects of individual elements.  This will help you figure out the location of any performance bottlenecks.

To run the Visual Profiler, start the WPF Performance Suite and click on the Visual Profiler tab.  Start your WPF application and then click Select Process under the Actions menu to select your process.

Once you connect the Visual Profiler to your application, you’ll see a variety of information, including:

  • A visual tree that indicates CPU time spent for layout of an element and its children
  • Measure/Arrange CPU usage for selected element
  • Application CPU usage breakdown

785-001

#784 – Using the Perforator Tool to Analyze WPF Application Performance

Once you install the WPF Performance Suite, you can use the tool to analyze the performance of your application.

After starting the WPF Performance Suite, click on the Perforator tab.

784-001

The next step is to run your WPF application.  Once the application is running, under the Actions menu, click on Select Process.

784-002

Select your application from the list and click the Select button.

784-003

The Perforator app will begin collecting data from your running WPF application and you’ll see various data displayed in the graphs.

784-004

Perforator is showing you the rendering performance of your application.  If nothing is being updated, both the Frame Rate and Dirty Rect Addition Rate graphs will report 0.  If you are updating something in you application, you generally want the frame rate to be as high as possible and the Dirty Rect Addition Rate to be as low as possible.

#783 – Downloading and Installing the WPF Performance Suite

There is a set of tools, known as the WPF Performance Suite, that you can use to analyze the performance of your WPF applications.

To get access to the WPF Performance Suite, you start by installing the Windows SDK 7.1 .  During the install, check the Windows Performance Toolkit option.

783-002

Once installed, you can find the WPF Performance Suite in the start screen under the Microsoft Windows Performance Toolkit section.

783-003

 

The first time that you run the WPF Performance Suite, you’ll see an Add Tools dialog.  Check the options for Perforator and Visual Profiler.

783-004

 

When the performance suite starts up, you’ll see an application with tabs labeled Perforator and Visual Profiler.

783-005

 

#766 – WPF Data Binding Ignores Custom Formatting

You can get the WPF data binding engine to respect the current locale, as specified in the Region applet, by setting the Language property of a FrameworkElement to the language tag that is part of the CurrentCulture property.

Doing this allows you to set up the proper locale in a single line of code and data binding will use the correct rules for formatting dates and floating point numbers for the appropriate language.

This mechanism won’t, however, honor any custom formatting that you specify in the Region applet.  A custom format is anything that you change from the defaults in the Region applet.

766-001

If you want the data binding engine to completely respect all of the settings chosen in the Region applet, you can set the ConverterCulture property to the CurrentCulture, for each binding.

        <TextBlock Text="{Binding BoundDate, ConverterCulture={x:Static glob:CultureInfo.CurrentCulture}}"/>

The glob namespace points to System.Globalization.

766-002

#765 – WPF Data Binding Ignores CurrentCulture

Using the ToString method on numeric and date-based types from within your code, the output will reflect the current culture, as stored in the CurrentCulture property of the current thread.

When the data binding mechanism in WPF converts numeric or date-based data to a string, however, it doesn’t automatically use the current culture.  Instead, you must set the Language property of the FrameworkElement where the binding is occurring.  You typically set this property based on the CurrentCulture property of the current thread.  You can set the Language property of the topmost user-interface element, so that all of the other elements inherit the value.

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

            this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
        }

We can now do binding as follows (where BoundDate property is of type DateTime):

        <TextBlock Text="{Binding BoundDate, StringFormat=d}"/>

Now if we run with the region set to French (France), we see:
765-001

#764 – Current Culture Is Used When Converting Data to A String

The CurrentCulture property of a Thread object indicates a user’s current locale, as set in the Region applet.  This value can normally be thought of as indicating the user’s location.

If you convert either numeric or date data to a string, the formatting used will depend on the current locale, as set in the Region applet and reported by the CurrentCulture property.

For example:

            double d1 = 123.456;
            DateTime date1 = DateTime.Now;

            string output = string.Format("123.456 => {0}\nNow => {1}",
                d1.ToString(),
                date1.ToString());

            MessageBox.Show(output);

If we run this code when our region is set to English (United States), we get:

764-001

But now if we switch our region to French (France) and re-run the application, we get:

764-002

Notice that the decimal point is now displayed as a comma (,) and the date format is dd/mm, rather than mm/dd.

#763 – The Difference Between CurrentCulture and CurrentUICulture

In a WPF application, you have access to two properties that give you information about the user’s culture and language.  They are both properties of a Thread object, which you can access via Thread.CurrentThread.

  • CurrentCulture – Tells you the user’s current locale, as set in the Region applet.  I.e.: Where is the user located?
  • CurrentUICulture – Tells you the native language of the version of Windows that is installed.  I.e.: What language does the user speak?

The user can change CurrentCulture using the Region applet.  It’s used to determine formatting for numeric and date/time strings.

763-001

The user normally can’t change CurrentUICulture without re-installing Windows.  It’s used to know what language to use when displaying text in your application.  (I.e. Which resource files to load).

            CultureInfo ci = Thread.CurrentThread.CurrentCulture;
            lblCurrentCulture.Content = string.Format("CurrentCulture = {0} - {1}", ci.Name, ci.DisplayName);

            ci = Thread.CurrentThread.CurrentUICulture;
            lblCurrentUICulture.Content = string.Format("CurrentUICulture = {0} - {1}", ci.Name, ci.DisplayName);

For example, someone in England might see:
763-002

Ad Free

I’ve turned off ads on 2,000 Things You Should Know about WPF.  For a full explanation, click here.

#728 – Using the Clipboard to Transfer Other Types of Data

As with drag-and-drop, you can transfer data between two running WPF applications in a variety of formats, using the clipboard.

The full list of data formats that you can specify is listed as a set of static fields in the System.Windows.DataFormats class.  Keep in mind that these are just labels used by the two applications to communicate with each other what data format is being transfered.

Below is an example of transfering some Xaml data between two applications using the clipboard.

On the copy side:

        private void btnCopy_Click(object sender, RoutedEventArgs e)
        {
            string xaml = XamlWriter.Save(e.Source);
            DataObject data = new DataObject(DataFormats.Xaml, xaml);

            Clipboard.SetDataObject(data);
        }

On the paste side:

        private void btnPaste_Click(object sender, RoutedEventArgs e)
        {
            IDataObject data = Clipboard.GetDataObject();
            if (data.GetDataPresent(DataFormats.Xaml))
            {
                string xaml = (string)data.GetData(DataFormats.Xaml);
                MessageBox.Show(xaml);
            }
        }

728-001
728-002