Example #1
0
        public static void SetPropertyValue(object ctrl, string propertyName, object value, params object[] args)
        {
            // The first thing we have to do is figure out if we can tell whether or
            //   not we're on the right thread.  If we can't tell that, then this
            //   whole thing is useless.
            bool   needsInvoke = false;
            object parent      = ctrl;
            // Get the object's Type.
            Type         objType  = ctrl.GetType();
            PropertyInfo piInvoke = null;

            // Try and see if the passed object has a property called
            //   "InvokeRequired".  Probably not, so...
            if ((piInvoke = objType.GetProperty("InvokeRequired")) != null)
            {
                object retVal = piInvoke.GetValue(ctrl, null);
                needsInvoke = (retVal == null || retVal.GetType().Name != "Boolean") ? false : (bool)retVal;
            }
            else if ((piInvoke = objType.GetProperty("Owner")) != null || (piInvoke = objType.GetProperty("Parent")) != null)
            {
                // If it doesn't have the "InvokeRequired" property, we check to
                //   see if it has a property named "Owner"
                object owner = piInvoke.GetValue(ctrl, null);
                if (owner != null)
                {
                    // If it does, grab the owner and get it's Type.
                    Type ownType = owner.GetType();
                    // Now we'll check to see if the owner has an "InvokeRequired"
                    //   property. This is the way ToolStripMenus and ToolBarMenus
                    //   work.
                    PropertyInfo pOwn = ownType.GetProperty("InvokeRequired");
                    if (pOwn != null)
                    {
                        object retVal = pOwn.GetValue(owner, null);
                        needsInvoke = (retVal == null || retVal.GetType().Name != "Boolean") ? false : (bool)retVal;
                        // We have to remember which object defines our current
                        //   thread context.
                        parent = owner;
                    }
                }
            }
            else
            {
                // If none of that worked, then we can't figure it out, so just throw
                //   an error.  Otherwise we'll end up triggering one by accident or
                //   in an infinate loop.
                throw new ArgumentException("Cannot determine thread context from the given object.");
            }


            // If made it this far, we found some way to determine thread context, so
            //   now this starts to look a little more familiar.
            if (needsInvoke)
            {
                // The 'parent' variable will be a reference to either the passed
                //   object or it's owner, if an "Owner" property was found.  This,
                //   also, is for ToolStripMenus and ToolBarMenus.  Individual
                //   ToolBarButtons and ToolStripMenuItems do not have "Invoke" or
                //   "BeginInvoke" methods.  We have to call their owner's methods.
                Type       parType    = parent.GetType();
                Type[]     paramTypes = new Type[] { typeof(Delegate), typeof(object[]) };
                MethodInfo miInvoke   = null;
                // Create the delegate like normal;
                SetObjectPropertyValueDelegate del = new SetObjectPropertyValueDelegate(CrossThreadUI.SetPropertyValue);
                // Then try and find the "Invoke" or "BeginInvoke" method. If we
                //   don't find either, we have to throw an exception.
                if (CrossThreadUI.ExecSync && ((miInvoke = parType.GetMethod("Invoke", paramTypes)) != null))
                {
                    miInvoke.Invoke(parent, new object[] { del, new object[] { ctrl, propertyName, value, args } });
                }
                else if ((miInvoke = parType.GetMethod("BeginInvoke", paramTypes)) != null)
                {
                    miInvoke.Invoke(parent, new object[] { del, new object[] { ctrl, propertyName, value, args } });
                }
                else
                {
                    throw new ArgumentException("Specified object does not expose any default methods for invoking methods on its executing thread.");
                }
            }
            else
            {
                // Now that we've determined thread context and decided we're on the
                //   correct thread, lets set the property value.
                PropertyInfo pi = objType.GetProperty(propertyName, CrossThreadUI.Binding);

                // Make sure the passed object's Type matches the property's Type.
                if (pi.PropertyType != typeof(System.String) && !value.GetType().IsAssignableFrom(pi.PropertyType))
                {
                    throw new ArgumentException("Value Type does not match property Type.", "value");
                }

                if (pi != null)
                {
                    try
                    { pi.SetValue(ctrl, ((pi.PropertyType.FullName == "System.String") ? value.ToString() : value), args); }
                    catch { throw; }
                }
            }
        }
        /// <summary>
        /// Sets the specified property value on an object that does not inherit from System.Windows.Forms.Control.  An exception will be thrown if the control
        /// does not expose a property with the specified name or it has neither an 'InvokeRequired' property nor an 'Owner' or 'Parent' property with
        /// an 'InvokeRequired' property.
        /// </summary>
        /// <param name="ctrl">The object instance whose property will be set.</param>
        /// <param name="propertyName">The name of the Property member that will receive the new value.</param>
        /// <param name="value">The value to assign to the property.  This object must be properly typed to match the property's signature.</param>
        /// <param name="args">Any optional arguments that must be provided to access this property.  Array objects must be properly typed to match property's signature.</param>
        public static void SetPropertyValue(object ctrl, string propertyName, object value, params object[] args)
        {
            // The first thing we have to do is figure out if we can tell whether or
            //   not we're on the right thread.  If we can't tell that, then this
            //   whole thing is useless.
            bool needsInvoke = false;
            object parent = ctrl;
            // Get the object's Type.
            Type objType = ctrl.GetType();
            PropertyInfo piInvoke = null;

            // Try and see if the passed object has a property called
            //   "InvokeRequired".  Probably not, so...
            if ((piInvoke = objType.GetProperty("InvokeRequired")) != null)
            {
                object retVal = piInvoke.GetValue(ctrl, null);
                needsInvoke = (retVal == null || retVal.GetType().Name != "Boolean") ? false : (bool)retVal;
            }
            else if ((piInvoke = objType.GetProperty("Owner")) != null || (piInvoke = objType.GetProperty("Parent")) != null)
            {
                // If it doesn't have the "InvokeRequired" property, we check to
                //   see if it has a property named "Owner"
                object owner = piInvoke.GetValue(ctrl, null);
                if (owner != null)
                {
                    // If it does, grab the owner and get it's Type.
                    Type ownType = owner.GetType();
                    // Now we'll check to see if the owner has an "InvokeRequired"
                    //   property. This is the way ToolStripMenus and ToolBarMenus
                    //   work.
                    PropertyInfo pOwn = ownType.GetProperty("InvokeRequired");
                    if (pOwn != null)
                    {
                        object retVal = pOwn.GetValue(owner, null);
                        needsInvoke = (retVal == null || retVal.GetType().Name != "Boolean") ? false : (bool)retVal;
                        // We have to remember which object defines our current
                        //   thread context.
                        parent = owner;
                    }
                }
            }
            else
                // If none of that worked, then we can't figure it out, so just throw
                //   an error.  Otherwise we'll end up triggering one by accident or
                //   in an infinate loop.
                throw new ArgumentException("Cannot determine thread context from the given object.");


            // If made it this far, we found some way to determine thread context, so
            //   now this starts to look a little more familiar.
            if (needsInvoke)
            {
                // The 'parent' variable will be a reference to either the passed
                //   object or it's owner, if an "Owner" property was found.  This,
                //   also, is for ToolStripMenus and ToolBarMenus.  Individual
                //   ToolBarButtons and ToolStripMenuItems do not have "Invoke" or
                //   "BeginInvoke" methods.  We have to call their owner's methods.
                Type parType = parent.GetType();
                Type[] paramTypes = new Type[] { typeof(Delegate), typeof(object[]) };
                MethodInfo miInvoke = null;
                // Create the delegate like normal;
                SetObjectPropertyValueDelegate del = new SetObjectPropertyValueDelegate(CrossThreadUI.SetPropertyValue);
                // Then try and find the "Invoke" or "BeginInvoke" method. If we
                //   don't find either, we have to throw an exception.
                if (CrossThreadUI.ExecSync && ((miInvoke = parType.GetMethod("Invoke", paramTypes)) != null))
                    miInvoke.Invoke(parent, new object[] { del, new object[] { ctrl, propertyName, value, args } });
                else if ((miInvoke = parType.GetMethod("BeginInvoke", paramTypes)) != null)
                    miInvoke.Invoke(parent, new object[] { del, new object[] { ctrl, propertyName, value, args } });
                else
                    throw new ArgumentException("Specified object does not expose any default methods for invoking methods on its executing thread.");
            }
            else
            {
                // Now that we've determined thread context and decided we're on the
                //   correct thread, lets set the property value.
                PropertyInfo pi = objType.GetProperty(propertyName, CrossThreadUI.Binding);

                // Make sure the passed object's Type matches the property's Type.
                if (pi.PropertyType != typeof(System.String) && !value.GetType().IsAssignableFrom(pi.PropertyType))
                    throw new ArgumentException("Value Type does not match property Type.", "value");

                if (pi != null)
                    try
                    { pi.SetValue(ctrl, ((pi.PropertyType.FullName == "System.String") ? value.ToString() : value), args); }
                    catch { throw; }
            }
        }