hello,
i'm new to c# and as school assignment, I
need to make a marque where when a button is clicked a text from a text box would be sent to a label and the label will move left to right as a marquee. and delegate must be command to be used to move the string.

The codes below are what I have done so far, please help.

Thanks
Ernst

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;



namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {


        public Form1()
        {
            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = textBox1.Text;

        }

    }

Edited 3 Years Ago by mike_2000_17: Fixed formatting

Hi ernst1234, welcome at daniweb!
Please use code tags when you post code.
Use the Location property of the Label to move it.
You have to use the Refresh() method of the form to make that happen.

i tried to move the location of my X coordinate this is what i came up with

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    {
        int X = 31;

        public Form1()
        {
            InitializeComponent();
           

        }

        private void button1_Click(object sender, EventArgs e)
        {
            label1.Text = textBox1.Text;

            while (X > 171)
            {
                label1.Location = new Point(X, 105);
                X++;
            }
        }

    }
}

Hi ernst1234,

Here are some more tips for you to get moving on this assignment:

* You will want to measure the size of the string in the label and resize the width of the label control to ensure the text does not exceed the window region: Graphics.MeasureString

* Then, you can use the above to adjust the Label.Size * As ddanbe already mentioned, you can move the label by changing the Label.Location property inside a loop (don't forget to call label.Refresh() method afterwards).

* To control the delay in the loop, check out this.Thread.Sleep(...) * As far as the delegate is concerned, that's just a type that references a method, and you just need to determine when and what method you will call. See: Delegates

Edited 6 Years Ago by DdoubleD: n/a

The other option is to leave the label where it is and scroll the text instead.
Whichever way you do it, you will need some kind of timing mechanism. I would use a timer with a low interval and change the text/position in its OnTick event. But if you have been told to use a delegate then it sounds like they may intend for you to use threading. In which case you need to run a thread which will access your label via a delegate (sicne threads cannot directly access the UI thread) to change its text/position then set the thread to sleep for a short period.

If you dont use a timer to slow it down your code will run in a fraction of a second and your marque will appear to go from start to finish in one jump.

i cant make the loop to work. is this where the delegate comes in??

namespace WindowsFormsApplication4
{
    public partial class Form1 : Form
    { 
        

        Thread t;
        public Form1()
        {
            InitializeComponent();
            t = new Thread(moveLabel);
            
        }

        private void button1_Click(object sender, EventArgs e)
        {

            label1.Text = textBox1.Text;
            t.Start();
        }

        private void moveLabel()
       {
           for(int i = 31; i<131; i++)
       
           {
                label1.Location = new Point(31+1,151);
               
                Thread.Sleep(100);
                label1.Refresh();
           }
            
            t.Abort();
        }
    }
}

Yes, i would imagine you are getting an exception because of an IllegalCrossThreadCall. You are correct, this is where you need a delegate.

You use a delegate to access the controls of the UI, it is similar to creating a Public Property to allow access to private fields:

//create a method to perform the changes to the UI
private void updateLabelLocation(Point p)
{
    label1.Location = p;
    label1.Refresh();
}

//then create your delegate which will allow your thread to invoke the method
public delegate void DelegateUpdateLabelLocation(Point p);

//then inside your thread you invoke the delegate
Point newPoint = new Point(32, 151);
this.Invoke(new DelegateUpdateLabelLocation(updateLabelLocation), newPoint);

Edited 6 Years Ago by Geekitygeek: code typo

Your last code never moves your label, look at line 27.
Put in the loop variable somewhere.
Do not Refresh the label, refresh the form.

I think you may have meant label1.Location = new Point(31+i,151); .

@ddanbe:
Hmm, i used label.Refresh() when i tested the code sample i gave and the label moved. When i read your post i took the refresh line out all together (out of curiosity) and the label still moves without any call to refresh.
As i understand it, when a control becomes invalidated it is marked for redraw. The redraw happens when the application is next idle, but Refresh forces the redraw immediately.
My guess is that altering the Location member invalidates the control and since my app is idle it redraws right away :)
Is there any reason why you should us form.Refresh rather than control.Refresh? If its just the control that has changed wouldnt it be more efficient to only redraw that?

@Ryshad:
Yes, you are quite right here. I was a bit confused, because some time ago I had an app with a label of which I wanted to update the text. It would only update if I called Refresh. So I wrongly thought this would hold for Location also. Never to old to learn something!:)
Thanks!

Thats what daniweb is for...we all teach each other :)
I've done a little digging but couldnt find any concrete info on this; calling invalidate/refresh will invalidate a control, but there are certain events that seem to do this too (like minimising the form, covering it with another window, etc). My guess is that changing the location is one of the thigns that automatically invalidates the control.

There is a distinction between invalidate and refresh that gets confused sometimes. Invalidate (wether called by user or behind the scenes) flags the control for repainting whenever the UI thread gets around to it, Refresh invalidates the control and forces the UI thread to paint it right away. For most things Invalidate is enough, but if your app might be tied up in another process and you need an immediate update to the visuals then its best to call Refresh.

The man who can no longer learn is dead :p

Comments
Well said!
This article has been dead for over six months. Start a new discussion instead.