Use Int32 as DataMemberBinding of RadColorPickerColumn instead of Color

4 posts, 0 answers
  1. Quang Khải
    Quang Khải avatar
    16 posts
    Member since:
    Dec 2015

    Posted 07 Dec 2017 Link to this post

    In order to create a Custom editor with RadGridView by following a guide at: Create Custom Editor with RadGridView

    It looks OK, but I would change the DataMemberBinding to Int32 instead of System.Windows.Media.Color, because System.Windows.Media.Color belongs to View class I don't really want to use it in my ViewModel. The converter looks like:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
          int num= System.Convert.ToInt32(value);
          Color color;
          byte[] bytes = BitConverter.GetBytes(num);
          color = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);
          return new SolidColorBrush(color);     
     }

     

    The converter get correct value for control, but when I change color from CorlorPicker, it get validation error in the cell and it says: Object of type "System.Windows.Media.Color" cannot be converted to type "System.Int32".

    Any idea to resolve the problem? Thanks in advance.

     

  2. Quang Khải
    Quang Khải avatar
    16 posts
    Member since:
    Dec 2015

    Posted 08 Dec 2017 in reply to Quang Khải Link to this post

    To be clear, the exception thrown by the picker control internally.

    System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=Color; DataItem='MyVM' (HashCode=7290323); target element is 'CustomColorPicker' (Name=''); target property is 'SelectedColor' (type 'Color') ArgumentException:'System.ArgumentException: Object of type 'System.Windows.Media.Color' cannot be converted to type 'System.Int32'.
       at System.RuntimeType.TryChangeType(Object value, Binder binder, CultureInfo culture, Boolean needsSpecialCast)
       at System.Reflection.MethodBase.CheckArguments(Object[] parameters, Binder binder, BindingFlags invokeAttr, CultureInfo culture, Signature sig)
       at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)
       at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value)
       at System.Windows.Data.BindingExpression.UpdateSource(Object value)'
  3. Dinko
    Admin
    Dinko avatar
    473 posts

    Posted 12 Dec 2017 Link to this post

    Hello Jacky Phan,

    In case you want to change the example in the Create Custom Editor with RadGridView to use int instead of color you can modify the CreateValueBinding() method (from the article). You can set the Converter property of the binding. This way when you are in edit mode and choose a color the ConvertBack() method of the ColorToBrushConverter will be called. To workaround the error you can return int instead of color. Check the following code snippets.
    private Binding CreateValueBinding()
    {
        Binding valueBinding = new Binding();
        valueBinding.Mode = BindingMode.TwoWay;
        valueBinding.Converter = new ColorToBrushConverter();
        valueBinding.NotifyOnValidationError = true;
        valueBinding.ValidatesOnExceptions = true;
        valueBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
        valueBinding.Path = new PropertyPath(this.DataMemberBinding.Path.Path);
        return valueBinding;
    }
    public class ColorToBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
     
            int num = System.Convert.ToInt32(value);
            Color color;
            byte[] bytes = BitConverter.GetBytes(num);
            color = Color.FromArgb(bytes[3], bytes[2], bytes[1], bytes[0]);
            return new SolidColorBrush(color);
            //var color = (Color)value;
            //if (color != null)
            //{
            //    return new SolidColorBrush(color);
            //}
            //return value;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            string colorcode = value.ToString();
            int argb = Int32.Parse(colorcode.Replace("#", ""), NumberStyles.HexNumber);
            return argb;
        }
    }

    Give this approach a try and let me know if it works for you.

    Regards,
    Dinko
    Progress Telerik
    Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
  4. Quang Khải
    Quang Khải avatar
    16 posts
    Member since:
    Dec 2015

    Posted 13 Dec 2017 in reply to Dinko Link to this post

    Thanks for the answer, it works properly.

    It seems we have 2 converters, one for cellcontrol, one for value binding.

Back to Top