Showing posts with label xaml. Show all posts
Showing posts with label xaml. Show all posts

Visual Studio Hanging

Do get lots of hangs in Visual Studio where the window fails to redraw when scrolling, some windows don’t paint – and then VS finally hangs. It appears this is because you are hitting the default 10,000 GDI object per process limit. This seems to happen to me quiet often when viewing xaml files (in vs2008).

You can see the GDI Object count in Process Explorer or if Task Manager - by clicking on the view -> select columns menu and ticking GDI Objects.

You can't fix this as far as I know but you can delay the inevitable by increasing the limit.

See this link for information on how to change the GDIProcessHandleQuota limit in the registry: http://msdn.microsoft.com/en-us/library/ms724291(VS.85).aspx

I set the limit to 15,000 on my windows 7 64 bit desktop with 4 gig of ram and haven't had any issues.

For more detailed information on GDI Objects see this page: http://blogs.technet.com/markrussinovich/archive/2010/03/31/3322423.aspx

A better way to declare your ValueConverters in XAML

Generally most people define a resource like this "<conv:AdditionConverter x:Key="AdditionConverter" />" and then use the converter like this "{Binding Converter="{StaticResource NegatingConverter}} "

This is OK but it’s fairly verbose and leads to converters being defined all over the place. An alternative is to use a MarkupExtension to minimize the amount of XAML code required. E.g.:


    public class AdditionConverter : MarkupExtension, IValueConverter
    {
        private static AdditionConverter _converter;

        public object Convert(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
            // convert and return something
        }

        public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
        {
            // convert and return something (if needed)
        }

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
                _converter = new AdditionConverter();
            return _converter;
        }
    }

Doing this you no longer need to define a resource as the XAML parser knows how to ask the markup extension to supply the converter. You end up with a syntax like this:
{Binding Converter={conv:MyConverter}} 

This approach has an added advantage of ensuring that all your converters are singletons.



Taking it further: Making a wrapper base class

This article explains a generic markup extension class that hides the MarkupExtension implementation details and makes the process above even easier.

ConverterMarkupExtension.cs

using System;
using System.Windows.Data;
using System.Windows.Markup;

namespace sfc.Converters
{
    [MarkupExtensionReturnType(typeof(IValueConverter))]
    public abstract class ConverterMarkupExtension :
    MarkupExtension where T : class, IValueConverter, new()
    {
        private static T _converter;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
            {
                _converter = new T();
            }
            return _converter;
        }
    }

    [MarkupExtensionReturnType(typeof(IMultiValueConverter))]
    public abstract class MultiConverterMarkupExtension :
    MarkupExtension where T : class, IMultiValueConverter, new()
    {
        private static T _converter;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
            {
                _converter = new T();
            }
            return _converter;
        }
    }
}

There are 2 classes here, one for IValueConverter's and one for IMultiValueConverters.

You can then modify your classes to inherit from this class and they nolonger need to worry about implementing MarkupExtension E.g.:

    public class AdditionConverter : ConverterMarkupExtension<AdditionConverter>
    {
        public object Convert(object  value, Type targetType, 
        object  parameter, System.Globalization.CultureInfo culture)
        {
            // convert and return something
        }

        public object  ConvertBack(object value, Type  targetType, 
        object parameter,  System.Globalization.CultureInfo culture)
        {
            // convert and return something (if needed)
        }
    }



How to obtain access to nested types through XAML

Answer: "+" indicates nested type in XAML

For example I want to access the View member on the Shipping type which is nested inside the Setup type e.g.

public struct Setup
{
  public struct Shipping
  {
    public const string View = "This is the value I want to access";
  }
}

The syntax would be CommandParameter="{x:Static demoAlias:Setup+Shipping.View}"