ColorEditBox Value

Editors for WPF Forum

Posted 12 years ago by Colin Kemp
Version: 11.2.0551
Avatar
To Whom It May Concern,


I am trying to Set the ColorEditBox Value thru a binding like this


  <Converters:ColorStringConverter x:Key="ColorConverter"/>

  <editors:ColorEditBox
    Width="56"
    Format="#RXGXBX"
    CheckBoxVisibility="Visible"
    IsAlphaComponentVisible="False"
    IsChecked="{Binding Path=IsSelected, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
    Value="{Binding Path=ColorString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

   <!--no matter what i try I can not get the color to change. 
      I have even injected a Converter that returns a Color object & 
      I also tried to set the Initial Value. 
      My Value is a string like this #FFFF00 -->

<!--Value="{Binding Path=ColorString, Converter={StaticResource ColorConverter},Mode=TwoWay}-->
<!--InitialValue="{Binding Path=ColorString, Converter={StaticResource ColorConverter}}"-->

Here is the Converter

    internal class ColorStringConverter:
        IValueConverter
    {
        #region IValueConverter Members

        public object Convert
               (
                   object value, 
                   Type targetType, 
                   object parameter, 
                   System.Globalization.CultureInfo culture
                )
        {
            SolidColorBrush m_ColorBrush = new SolidColorBrush(Colors.White);
            try
            {
                BrushConverter m_ColorCon = new BrushConverter();
                m_ColorBrush = (SolidColorBrush)m_ColorCon.ConvertFromString(value.ToString());
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show("ERROR:" + ex.Message + " STACK<" + ex.StackTrace + ">")               
            }
            return m_ColorBrush.Color;
        }

        public object ConvertBack
           (
              object value, 
              Type targetType, 
              object parameter, 
              System.Globalization.CultureInfo culture
            )
        {
            throw new NotImplementedException();
        }

        #endregion IValueConverter Members
Any suggestions & Code Samples Would be greatly appreciated

Colin

Comments (7)

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Colin,

That's not something we've heard of, but you can't really have a TwoWay binding with a converter that doesn't implement ConvertBack.

Either way, if you can please put together a small sample project that reproduces your issue and email it over then we can take a closer look. Be sure to remove any executables or change the extension of the zip file to ensure it gets past our email filters.


Actipro Software Support

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Colin,

Thank you for the sample. You need to use the IValueConverter like you have, but again you would have to implement the ConvertBack in order to support two-way bindings.

Even with that in there, your ColorString is not valid. You initialize it to "#FFF0H2", which is not a valid color so your IValueConverter would throw an exception.


Actipro Software Support

Posted 12 years ago by Colin Kemp
Avatar
upon further review you do not need the IValueConverter at all.

<Window x:Class="SampleColorEditProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <editors:ColorEditBox Margin="10,10,0,0"
                              Format="#rxgxbx"
                              InitialValue="Black"
                              VerticalAlignment="Top"
                              HorizontalAlignment="Left"
                              MinWidth="250"
                              Value="{Binding 
                                      Path=ColorString, 
                                      UpdateSourceTrigger=PropertyChanged, 
                                      Mode=TwoWay, 
                                      StringFormat=#rxbxgx}"
                              IsAlphaComponentVisible="True"
                              CheckBoxPlacementSlot="Left"
                              CheckBoxInactiveVisibility="Visible"
                              EditableParts="All"
                              Height="25" IsChecked="True" />

    </Grid>
</Window>
this XAML snippet Works just fine in the sample app that I provided. Sorry about the bad color string. I may have a new issue, but I will do more diligence this time before I post.



Colin

[Modified at 01/25/2012 06:55 AM]
Posted 12 years ago by Colin Kemp
Avatar
Here is my new Issue. Is it possible to set the value of the ColorEditBox when the ColorEditBox is in a DataTemplate?

MyView

<Window x:Class="SampleColorEditProject.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:editors="http://schemas.actiprosoftware.com/winfx/xaml/editors"
        xmlns:Local="clr-namespace:SampleColorEditProject"
        Title="MainWindow" Height="350" Width="525">
    <Grid>

        <ListBox
            ItemsSource="{Binding ColorCollection}">
            <ListBox.ItemTemplate>
                <DataTemplate DataType="{x:Type Local:MyModel}">
                    <editors:ColorEditBox Margin="10,10,0,0"
                              Format="#rxgxbx"
                              InitialValue="Black"
                              VerticalAlignment="Top"
                              HorizontalAlignment="Left"
                              MinWidth="250"
                              Value="{Binding Path=ColorString, 
                                              UpdateSourceTrigger=PropertyChanged, 
                                              Mode=TwoWay, 
                                              StringFormat=#rxbxgx}"
                              IsAlphaComponentVisible="True"
                              CheckBoxPlacementSlot="Left"
                              CheckBoxInactiveVisibility="Visible"
                              EditableParts="All"
                              Height="25" IsChecked="True" />
                </DataTemplate>
            </ListBox.ItemTemplate>

        </ListBox>
    </Grid>
</Window>
Code Behind the View

using System.Windows;

namespace SampleColorEditProject
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow: Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MyViewModel();
        }
    }
}
My ViewModel

using System.Collections.ObjectModel;

namespace SampleColorEditProject
{
    internal class MyViewModel
    {
        #region ~ Properties ~

        /// <summary>
        /// The ColorCollection Property
        /// </summary>
        /// <value>My Property Value Description</value>
        public ObservableCollection<MyModel> ColorCollection
        {
            get
            {
                if (m_ColorCollection == null)
                {
                    m_ColorCollection = new ObservableCollection<MyModel>();
                }
                return m_ColorCollection;
            }
        }
        private ObservableCollection<MyModel> m_ColorCollection;

        #endregion ~ Properties ~

        #region ~ Constructor(s) ~

        /// <summary>
        ///
        /// </summary>
        public MyViewModel()
        {
            for (int i = 0; i < 10; i++)
            {
                this.ColorCollection.Add
                    (
                        new MyModel()
                    );
            }
        }

        #endregion ~ Constructor(s) ~
    }
}
My Model

using System;
using System.ComponentModel;
using System.Linq;

namespace SampleColorEditProject
{
    internal class MyModel: INotifyPropertyChanged
    {
        #region Field(s) ~

        private Random m_Random = new Random();

        #endregion Field(s) ~

        #region ~ Properties ~

        /// <summary>
        /// The ColorString Property
        /// </summary>
        public string ColorString
        {
            get
            {
                return m_ColorString;
            }
            set
            {
                m_ColorString = value;
                OnPropertyChanged("ColorString");
            }
        }
        private string m_ColorString;

        #endregion ~ Properties ~

        #region ~ Constructor ~

        public MyModel()
        {
            string m_R = OnGetRandomHexNumber(2);
            string m_G = OnGetRandomHexNumber(2);
            string m_B = OnGetRandomHexNumber(2);
            //
            this.ColorString = "#FF" + m_R + m_G + m_B;
        }

        #endregion ~ Constructor ~

        #region ~ INotifyPropertyChanged ~

        /// <summary>
        ///
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        ///
        /// </summary>
        /// <param name="m_PropertyName"></param>
        protected void OnPropertyChanged(string m_PropertyName)
        {
            PropertyChangedEventHandler m_handler = PropertyChanged;
            //
            if (m_handler != null)
            {
                m_handler(this, new PropertyChangedEventArgs(m_PropertyName));
            }
        }

        #endregion ~ INotifyPropertyChanged ~

        #region ~ Function ~

        public string OnGetRandomHexNumber(int digits)
        {
            byte[] buffer = new byte[digits / 2];
            m_Random.NextBytes(buffer);
            string result = String.Concat
                 (buffer.Select
                    (x => x.ToString("X2")
                 ).ToArray());
            if (digits % 2 == 0)
                return result;
            return result + m_Random.Next(16).ToString("X");
        }

        #endregion ~ Function ~
    }
}
the Model Generates A Random Color. When you Debug the code the bindings appear to be working except for ColorEditBox being updated with ColorString value located in the Model.


Regards,
Colin
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Colin,

You would need to remove the IsChecked="True" part. There seems to be a bug in WPF, that is being triggered in your sample. Setting IsChecked to true results in the ColorEditBox setting it's Value property to a non-null value. So the IsChecked/Value property are somewhat tied together. If you set Value to a non-null value, then IsChecked will automatically be set to true.

It seems that the code that loads the DataTemplate will not set the Value property to your binding, if the Value property has been set by the IsChecked change handler. Either way, you don't need to explicitly set IsChecked.

On a side note, you need to make your m_Random static, so it's reused by all your view-models. Otherwise all your colors will most likely be the same, as they all create a new instance of Random with the same seed value (resulting in the same "random" numbers).


Actipro Software Support

Posted 12 years ago by Colin Kemp
Avatar
thanks for the Help I Will test this out.

the random number Generator is there for your entertainment purpose only.

Regards,
Colin
Posted 12 years ago by Colin Kemp
Avatar
Works Like a Charm! thanks A Millon
The latest build of this product (v24.1.1) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.