How do I feed values to the statusStrip from a form control?
Asked Answered
M

1

1

This is the context of my controls:

/*
Form
    StatusStrip
        ToolStripStatusLabel

    TableLayoutPanel
        MyGenioView
*/

So, MyGenioView is intercepting the MouseMove event handler. The code that is already there is for a rubber band rectangle. So I have:

public void MyMouseMove(Object sender, MouseEventArgs e)
{
    Point ptCurrent = new Point(e.X, e.Y);
    // If we "have the mouse", then we draw our lines.
    if (m_bHaveMouse)
    {
        // If we have drawn previously, draw again in
        // that spot to remove the lines.
        if (m_ptLast.X != -1)
        {
            MyDrawReversibleRectangle(m_ptOriginal, m_ptLast);
        }
        // Update last point.
        m_ptLast = ptCurrent;
        // Draw new lines.
        MyDrawReversibleRectangle(m_ptOriginal, ptCurrent);
    }

    // New code here
}

What I can't get my head around is that I want to set the value of statusStrip1.statusLabel from the MyGenioView MouseMove handler. I can't work out how to do it.

The code I want to use is:

OdGePoint3d pt = GetWorldCoordinates(ptCurrent);
String strCoordinate = String.Format("{0},{1}", ptCurrent.X, ptCurrent.Y);

But what is the right way to feed it to the main forms statusStrip object?

Thanks for your help.

Update:

I know how to set the text of a statusStrip label object. That is not my issue. My issue is related to context of my mouse handler event and it's relationship to the form. Please see the context of the controls as described at the start of the question. The comments so far have not taken that into account.

This is the current place in the form that I create the MyGenioView object (that receives the mouse handler):

private void viewToolStripMenuItem_Click(object sender, EventArgs e)
{
    OdDbDatabase TDDatabase = m_oGenioView.GetDatabase();

    if (m_oGenioViewCtrl != null)
        m_oGenioViewCtrl.DeleteContext();

    tableLayoutPanel.RowCount = 1;
    tableLayoutPanel.ColumnCount = 1;
    m_oGenioViewCtrl = new MyGenioView();
    m_oGenioViewCtrl.TDDatabase = TDDatabase;
    m_oGenioViewCtrl.ResetDevice(true);
    m_oGenioViewCtrl.Dock = DockStyle.Fill;
    m_oGenioViewCtrl.Margin = new Padding(1);
    tableLayoutPanel.Controls.Add(m_oGenioViewCtrl);
}
Monodrama answered 27/5, 2016 at 12:12 Comment(11)
Add a label to it in design time and set the Text of label.Repast
When you use the designer to add the status label to the StatusStrip then you get an identifier name for it. And it is simply toolStripStatusLabel1.Text = strCoordinate; Fairly unclear what went wrong with that.Keith
@RezaAghaei, I already have "statusLabel". I don't know how to access it from the given context.Monodrama
If you are in the same form, simply use this.toolStripStatusLabel1.Text = "Some text"; Repast
@HansPassant I know this. The whole point is that the variable toolStripStatusLabel is not accessible from MyGenioView.Monodrama
@RezaAghaei DId you not see the "context" that I displayed right at the start of the question? Thanks.Monodrama
Unfortunately I couldn't understand the meaning of that context! Do you have access to instance of your form? Where did you add event handler?Repast
@RezaAghaei I can't see how else to explain. The form has a tableLayoutPanel on it. That is assigned a MyGenioView object. I put a bit more code in the question. Does that help?Monodrama
You have multiple options to do it. 1- Inject an Action<Point> in the user control. uc.UpdateStatus = p=>this.toolStripStatusLabel1.Text = p.ToString(); 2- Create an event UpdateStatus in the user control and raise it in MouseMove and consume the event in the form. Also you can use the MouseMove event itself. 3- Use hierarchy of controls to access the form, for example in user control, this.ParentForm is the form, then you can use Controls collection of the form to find the status strip.Repast
Well, then make it accessible. Beyond changing its Modifiers property to Public, the cleanest way is to add a public property to your form class. Please fix your question and use the correct form class names.Keith
@HansPassant I don't know what is wrong with my question wording.Monodrama
R
4

You have multiple options to update status:

  1. Inject an Action<Point> in the user control
  2. Create a StatusUpdate event in the user control
  3. You also can access the control using hierarchy of controls, for example in the user control this.ParentForm is your parent form and you can find the target control using Controls collection or by making it public in the form.

The first two options are much better because decouple your control from the form and your user control can be used on many forms and other containers this way. Providing a way of updating status is up to container.

The best option is creating and consuming the event.

1- Inject an Action<Point> in the user control

Inject an Action<Point> in the user control and use it in MouseMove. To do so, put this in User Control:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Action<Point> StatusUpdate{ get; set; }

//Don't forget to assign the method to MouseMove event in your user control 
private void UserControl1_MouseMove(object sender, MouseEventArgs e)
{
    if (StatusUpdate!= null)
        StatusUpdate(e.Location);
}

And put this code on Form:

private void Form1_Load(object sender, EventArgs e)
{
    this.userControl11.StatusUpdate= p => this.toolStripStatusLabel1.Text=p.ToString();
}

2- Create a StatusUpdate event in the user control

Create a StatusUpdate event in the user control and raise it in MouseMove and consume the event in the form. Also you can use the MouseMove event itself.

To do so, put this code in user control:

public event EventHandler<MouseEventArgs> StatusUpdate;
public void OnStatusUpdate(MouseEventArgs e)
{
    var handler = StatusUpdate;
    if (handler != null)
        handler(this, e);
}

//Don't forget to assign the method to MouseMove event in your user control 
private void UserControl1_MouseMove(object sender, MouseEventArgs e)
{
    OnStatusUpdate(e);
}

And then put in form, put this code:

//Don't forget to assign the method to StatusUpdate event in form  
void userControl11_StatusUpdate(object sender, MouseEventArgs e)
{
    this.toolStripStatusLabel1.Text = e.Location.ToString();
}
Repast answered 27/5, 2016 at 12:50 Comment(2)
Great! I had to make a minor change to using Action<Point>. I used OdGePoint3d instead. And the bit in the form I had to do in another handler, where the user control gets created (for reasons, it is null in the form load method). I may change this in time. Thanks!Monodrama
You are welcome :) Glad to hear you've got the main idea. When you get the main idea and learned the pattern you can apply it and enhance it simply.Repast

© 2022 - 2024 — McMap. All rights reserved.