-2

In my project I have a user control; when a button on this user control is pressed I want it to change a variable which is stored on the main winform, not the user control.

How can this be done?

I've tried this

namespace.class.variable =

but it says it cannot be accessed due to it's protection.

Toby Smith
  • 1,505
  • 2
  • 15
  • 24
  • 1
    The best way would be to use events – Sami Kuhmonen May 13 '15 at 11:40
  • If variable is static then you probably need to make it public. – Adil May 13 '15 at 11:41
  • Can you talk me through that? @SamiKuhmonen – Toby Smith May 13 '15 at 11:42
  • Well, technically I want it to change another control's property. @Adil – Toby Smith May 13 '15 at 11:43
  • https://msdn.microsoft.com/en-us/library/aa645739%28v=vs.71%29.aspx – Sami Kuhmonen May 13 '15 at 11:43
  • You can pass the control object to class where you want to change but you may have more appropriate method for this. – Adil May 13 '15 at 11:48
  • I'm sorry, I'm very new to all this. I'm not being rude but could you either use smaller words or show me an example? xD @Adil – Toby Smith May 13 '15 at 11:50
  • Is that property static, if it is static and public then namespace.class.variable = some value would work at least – Adil May 13 '15 at 11:52
  • Thanks, I've got it to work with variables that are public/static... How would I do it with variable properties? @Adil – Toby Smith May 13 '15 at 12:00
  • Please consider moving to events as @SamiKuhmonen suggested. Calling public static variables outside of a usercontrol from inside the implementaton is very bad practice. I've added an answer to your question quickly describing events and provided a link with more information – irreal May 13 '15 at 12:03
  • Check this out, http://stackoverflow.com/questions/1665533/communicate-between-two-windows-forms-in-c-sharp – Adil May 13 '15 at 12:03

2 Answers2

0

A user control should be an isolated whole, a container. You need to use events.

Think about how you would make a regular Button control populate some text in a regular TextBox control?

The TextBox doesn't know about the button and the button doesn't know about your textbox. They are separate controls. What you do is subscribe to the button's click event, and then tell the textbox control to change it's text.

Similarly to that, your user control needs to provide and Event that you can trigger whenever a button click or some other action happens.

That is all that the control should do, provide an event and trigger it.

It is then appropriate for you to subscribe to that event from the form where you house your user control and in that event handler change the other control's property as needed.

The following is a brief example of how and Event works. Find more info here

This should be inside your user control

//A delegate that describe's your event's signature
public delegate void ChangedEventHandler(object sender, EventArgs e);

//The actual Event declaration
public event ChangedEventHandler Changed;

//When appropriate, trigger the event from the user control
if (Changed != null) {
  Changed(this, e);
}
irreal
  • 2,217
  • 18
  • 23
  • I'm sorry, but I'm still confused. If I have `button1` on `userControl1`, how do I make that button change the text in `label1` to "hello" if `label1` is not in the user control but is in the winform that `userControl1` is in? – Toby Smith May 13 '15 at 12:22
  • You shouldn't do it directly. That's what I'm telling you. Anything inside the UserControl **must not** access other controls outside of the user control. That's not what user controls are for. You may declare button1 to be public inside your user control, then from the form, subscribe to button1's click event, and from there set the text on label1. – irreal May 13 '15 at 12:25
0

Small intro to what you need to do. This is small MVP program which will show message when you click button.

    //Your MainForm class
    public class MainForm: Form,IMainView
    {

        public event Action ButtonClicked;

        public MainForm()
        {
            InitializeComponent();
            button.Click += (sender, args) => 
            {
                var handler = ButtonClicked;
                if (handler != null) handler(sender, args);
            };
        }

        public void ShowError(string message)
        {
            MessageBox.Show(message);
        }
    }

    //Your MainForm interface. What lies here will become accessible in Presenter
    public interface IMainView : IView
    {
        event Action ButtonClicked;
    }

    //View interface
    public interface IView
    {
        void ShowError(string message);
    }

    //Your MainForm Presenter class which will do all work behind GUI
    public class MainPresenter : BasePresenter<IMainView>
    {
        public MainPresenter(IMainView view)
            : base(view)
        {
            view.ButtonClicked += view_ButtonClicked;
        }

        void view_ButtonClicked()
        {
            View.ShowError("Clicked!");
        }
    }

    //Base class for all presenters
    public abstract class BasePresenter<TView> : IPresenter
        where TView : IView
    {
        protected TView View { get; private set; }

        protected BasePresenter(TView view)
        {
            View = view;
        }
    }

    //Presenter interface
    public interface IPresenter
    {
    }
Szer
  • 3,426
  • 3
  • 16
  • 36