Silverlight-About IValueConverter and TypeConverter

This post focus on how to use IValueConverter and TypeConverter.

IValueConverter is used to convert the datasource to data which can be displayed on surface, for example, converting url to image and displaying on surface, displaying float data as currency, bool  and Visibility conversion.

TypeConverter is used to convert string in XAML to other types value, for example, converting string as Double to be used by Wideth property.

Firstly, One assembly of my DataSet has one url whose property is image. Now, I want to convert url to image and display it in GataGrid. How can I do?

IValueConverter Usage:

1. Write an ImageConverter type and it carries on IValueConverter interface. Then realize Convert and ConvertBack method. Note: Convert method convert datasource to displayed data. ConvertBack method is send the displayed data to datasource under TwoWay mode.

    public class ImageConverter : IValueConverter

    {

        //Convert Data to Image when Loading Data  

        public object Convert(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture)

        {

            try

            {

                Uri uri = new Uri((string)value, UriKind.RelativeOrAbsolute);

                BitmapImage img = new BitmapImage(uri);

                return img;

            }

            catch

            {

                return new BitmapImage();

            }

        }

        //Convert Image to Data under TwoWay when Operating on Web

        public object ConvertBack(object value, Type targetType, object parameter,System.Globalization.CultureInfo culture)

        {

            BitmapImage img = value as BitmapImage;

            return img.UriSource.AbsoluteUri;

        }

    }

2. State ImageConvert in UserControl to convert data when binding DataGrid datasoure.

    <UserControl.Resources>

      <this:ImageConverter x:Key=“ImageCoverter”/>

    </UserControl.Resources>

3. Use Convert to convert in DataGrid.

    <sdk:DataGrid HorizontalAlignment=“Left”  AutoGenerateColumns=“False”   Name=“ShowCityList” VerticalAlignment=“Top” >

    <sdk:DataGrid.Columns>

    <sdk:DataGridTextColumn Header=“State” Binding=“{Binding AddrName}” IsReadOnly=“True”/>

    <sdk:DataGridTextColumn Header=“City” Binding=“{Binding CityName}” IsReadOnly=“True” />

    <sdk:DataGridTextColumn Header=“Zip” Binding=“{Binding TelNum}” IsReadOnly=“True” />

    <sdk:DataGridTemplateColumn Header=“CityImage”>

    <sdk:DataGridTemplateColumn.CellTemplate>

       <DataTemplate>

          <Image Source=“{Binding CityImageUrl, Mode=TwoWay, Converter={StaticResource ImageCoverter}}”></Image>

       </DataTemplate>

    </sdk:DataGridTemplateColumn.CellTemplate>

    </sdk:DataGridTemplateColumn>

    </sdk:DataGrid.Columns>

    </sdk:DataGrid>

4. The following code shows how to bind datasource for this DataGrid.

    public partial class MainPage : UserControl

    {

        public MainPage()

        {

            InitializeComponent();

            List<CityInformation> listCity = new List<CityInformation>()

            {

                new CityInformation(){

                    AddrName=“Alaska”,

                    CityName=“Juneau”,

                    Zip=“99801”,

                    CityImageUrl=http://sc.admin5.com/uploads/allimg/100211/105R34217-0.png&#8221;

                },

                new CityInformation()

                {

                    AddrName=“California”,

                    CityName=“San Francisco”,

                    Zip=“94101”,

                    CityImageUrl=http://sc.admin5.com/uploads/allimg/100211/105R333J-4.png&#8221;

                },

                new CityInformation()

                {

                    AddrName=“Florida”,

                    CityName=“Miami”,

                    Zip=“33101”,

                    CityImageUrl=http://sc.admin5.com/uploads/allimg/100211/105R31S6-9.png&#8221;

                },

                new CityInformation()

                {

                    AddrName=“New York”,

                    CityName=“New York City”,

                    TelNum=“10001”,

                    CityImageUrl=http://sc.admin5.com/uploads/allimg/100211/105R33342-7.png&#8221;

                }

            };

            this.ShowCityList.ItemsSource = listCity;

        }

    }

    ///<summary>

    ///City Information Entity Class

    ///</summary>

    public class CityInformation

    {

        private string _AddrName;

        private string _CityName;

        private string _Zip;

        private string _cityImageUrl;

        public string AddrName

        {

            get { return _AddrName; }

            set { _AddrName = value; }

        }

        public string CityName

        {

            get { return _CityName; }

            set { _CityName = value; }

        }

        public string Zip

        {

            get { return _Zip; }

            set { _Zip = value; }

        }

        public string CityImageUrl

        {

            get { return _cityImageUrl; }

            set { _cityImageUrl = value; }

        }

    }

Secondly, I want to create a custom control. I use centimeter as unit to set width, not pixel, how to do?

TypeConverter Usage:

1. Write SLConverter type to carry on TypeConverter calss. Rewrite CanConvertFrom method and ConvertFrom mnethod to convert String to Double and assign to custom control.

    public class CustomLengthConverter : TypeConverter

    {

        //Return a value which indicates if type converter can convert specified type object to type of this type converter.

        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)

        {

            if (sourceType == typeof(string))

            {

                return true;

            }

            return base.CanConvertFrom(context, sourceType);

        }

        //Convert specified value to the expected conversion type of this converter.

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)

        {

            if (value == null)

            {

                return new Double();

            }

            if (value is string)

            {

                string s = (string)value;

                if (s.Length == 0)

                {

                    return new Double();

                }

                //Divide influent string into two parts. Set 2cm*40 = 80 pixel for the first part.

                string[] arguments = s.Split(‘ ‘);

                if (arguments.Length != 2)

                {

                    return new Double();

                }

                else

                {

                    // If 1cm=40px

                    return InternalParseInput((double.Parse(arguments[0])*40).ToString());

                }

            }

            return base.ConvertFrom(context, culture, value);

        }

        //Format String as Double and return to property.

        public Double InternalParseInput(String inputString)

        {

            Double doubleValue;

            try

            {

                doubleValue = Double.Parse(inputString);

            }

            catch (Exception)

            {

                doubleValue = new Double();

            }

            return doubleValue;

        }

    }

2. Write one custom control RichTextBlock and add two new custom properties. One of them can convert cm to px and display on screen.

    public partial class RichTextBlock : UserControl

    {

        public RichTextBlock()

        {

            InitializeComponent();

        }

        [TypeConverter(typeof(CustomLengthConverter))]

        public Double txtWidth

        {

            get { return this.txtBlock.Width; }

            set { this.txtBlock.Width = value; }

        }

        public Double txtHeight

        {

            get { return this.txtBlock.Height; }

            set { this.txtBlock.Height = value; }

        }

    }

3. We can set custom property of this control.

<this:RichTextBlock VerticalAlignment=“Top” txtHeight=“150” txtWidth=“2 cm” />

Two Components Recommend:

Spire.Doc, is used to operate MS Word document for .Net and Silverlight, including basic manipulations (generate, open, edit documents), mail merge and other Word functions manipulations.

Spire.XLS, is used to operate MS Excel for .NET and Silverlight, including basic manipulations (generate, open, edit files), chart creation and data exporting.

Advertisements

5 thoughts on “Silverlight-About IValueConverter and TypeConverter

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s