views:

180

answers:

2

Actually i'm working with C# and already got DataBinding and Serialization to work. But now i'd like to combine both methods in one class and i have a little problem with it.

So let's start with a little sample class:

using System;
using System.Runtime.Serialization;
using System.Windows.Forms;

namespace MySample
{
    [DataContract(IsReference = true)]
    class SerializeAndBind : IExtensibleDataObject
    {
        [DataMember]
        private String bindedControlName;
        [DataMember]
        private String bindedPropertyName;

        private DateTime creationTime;

        [System.ComponentModel.Browsable(false)]
        public virtual ExtensionDataObject ExtensionData { get; set; }

        public event EventHandler CreationTimeChanged;

        public SerializeAndBind()
        {
            CreationTime = DateTime.Now;
        }

        public SerializeAndBind(Control ControlName, String PropertyName)
            : this()
        {
            InitializeDataBinding(ControlName, PropertyName);
        }

        [DataMember]
        public DateTime CreationTime
        {
            get
            {
                return creationTime;
            }
            set
            {
                creationTime = value;

                if (CreationTimeChanged != null)
                    CreationTimeChanged(this, EventArgs.Empty);
            }
        }

        public override string ToString()
        {
            return CreationTime.ToString();
        }

        [OnDeserialized]
        private void InitializeDataBindingAfterDeserialization(StreamingContext ctx)
        {
            if (bindedControlName != null)
            {
                Control control;

                control = FindControlByName(bindedControlName);

                if(control != null)
                    InitializeDataBinding(control, bindedPropertyName);
            }
        }

        private void InitializeDataBinding(Control ControlName, string PropertyName)
        {
            BindingSource bindingSource = new BindingSource();
            bindingSource.DataSource = this;
            Binding binding = new Binding(PropertyName, bindingSource, "CreationTime", true, DataSourceUpdateMode.OnPropertyChanged);
            binding.Format += new ConvertEventHandler(OnFormat);
            ControlName.DataBindings.Add(binding);

            bindedControlName = ControlName.Name;
            bindedPropertyName = PropertyName;
        }

        private void OnFormat(object sender, ConvertEventArgs e)
        {
            if (e.DesiredType == typeof(String))
            {
                e.Value = this.ToString();
            }
        }
    }
}

As you can see this class has a ctor which takes the Control and PropertyName to which you like to bind this object. For Serialization i save the Control and PropertyName as a string (saving the whole control would be a little to much ;-)).

And i added a function which will be called after deserialization. But as you can see there exists the function FindControlByName() within that doesn't exists.

Now i could start using Reflection to find the appropiate control, but for reflection i need some kind of starting point (i would say the form), but how can the class access this without knowing anything outside of itself?

Or is this just the wrong way to do it and i need a different design?

Any help would be appreciate, Oliver

A: 

Personally, I doubt that this is ever going to be "clean" - serialization works well for data, but not so well for objects tightly connected to objects outside of the serialization graph.

At the point of deserialization, the object is in the ether (in fact, DataContractSerializer doesn't even use any constructor). As such, it has no way of getting to a form, etc. You could perhaps do some horrible hacks with a static field (perhaps [ThreadStatic]) to hold the current form, but it would be brittle and ugly.

(I'm hopeful that somebody will have a better answer, though!)

Marc Gravell
+1  A: 

I agree with previous post, break out your processing from your data. Much cleaner and easier to debug, maintain and scale.

Ricardo Villamil