Search code examples
c#user-controlsinversion-of-control

How to extend UserControl with an Interface while using IoC


Using C#, we are using custom user controls that a shell form consumes. All custom user controls allow users to do some basic functions like:

Save() ValidateItem()

Our user controls are extending a class called ScopedUserControl.

public class ScopedUserControl : UserControl, IScopedControl
    {
        private ILifetimeScope _scope;

        public void SetLifetimeScope(ILifetimeScope scope)
        {
            _scope = scope;
        }

        #region IDisposable override
        private bool disposed = false;

        protected override void Dispose(bool disposing)
        {
            base.Dispose(disposing);

            if (!disposed)
            {
                if (disposing)
                {
                    _scope?.Dispose();
                }

                disposed = true;
            }
        }
        #endregion
    }

There is an interface here, used in conjunction with AutoFac IoC.

   public interface IScopedControl : IDisposable
    {
        void SetLifetimeScope(ILifetimeScope scope);
    }

What I wanted to do was have a generic shell form consume a user control. That user control would implement an interface called IEditBase

  public partial class ucDataGrid : ScopedUserControl, IEditBase
    {
      ...

Here is IEditBase

  public interface IEditBase 
    {
        bool ValidateItem();
        bool Save();
    }

Now when the user clicks on a toolbar save button in the shell of the form:

 public partial class frmEditShell : ScopedForm
    {
     ....
        private void tsbSave_Click(object sender, EventArgs e)
        {
            ((IEditBase)pnlControls.Controls[0]).Save();
            this.Close();
        }

I get this error: System.InvalidCastException: 'Unable to cast object of type 'View.ucDataGrid' to type 'Interface.IEditBase'.' on this line:

  ((IEditBase)pnlControls.Controls[0]).Save();

I don't think I can cast it because of the Interface in the extended class ScopedUserControl.

I think my design approach here might be flawed, or I am missing something. Thanks for your help.

M.


Solution

  • You have 2 interfaces with the name: IEditBase in different namespaces :) ucForecastWeightedEdit inherits a different interface than ucServiceItemOnLocation actually. If you unify it, everything will work as expected.