|
As an answer to your first question: you can add DataGridStyles to your Grid, in the designer and in code. Do this before you point the Grid to its datasource. If you program the available columns manually, you can set their Width and headertext too. All columns you want invisible, set the respective widths to 0.
You can also define a methodthat returns a DataGridStyle and add that to the Grids style, possibly deleting the old style (DataSource has to be null to do that I believe)
|
|
|
|
|
Hi!.
I wrote an application that start a thread that read some data from the communication port. The problem is that I want to put the data in a textbox, (text1), and I don't know how to do that . In C++ I just use a global variable, but how can I define a global variable in Visual C#.
How can I get data from the thread?.
Thank you very much.
Demian.
|
|
|
|
|
Global variables are looked down upon in the object-oriented world, and are not allowed in Java or C#. If you want to place text inside the textbox, just pass your textbox instance to the object reading your communication port.
Also note that Windows Forms controls are single threaded in nature; it's a no-no to modify them from a thread other than the thread that owns the handle to the control (ie the thread that the control was created on). Fortunately for you and I, all Windows Forms controls contain a method called .Invoke that lets you call a method on the control using the thread that owns the handle.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
sorry judah didnt get that last part! could u exemplify! thx in advance i was needing this for another app
|
|
|
|
|
See Heath's post below.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Use Control.InvokeRequired and Control.Invoke from threads other than the thread on which the control was created. Global variables are also not a very good way unless you use good locking when reading/writing from/to them (the lock keyword in C# is a simple way to do this using a monitor). To use a global variable, you can always use a static property or, if your threaded method is a method defined on the Control class that contains your TextBox , just use a private variable (and be sure to lock it).
To write to the text box, make sure your thread class or procedure has a reference to your TextBox (for example, you could thread a single method in your class which contains the TextBox reference). If you're not sure if your method would be threaded or not, use the code below (otherwise eliminate the check for Control.InvokeRequired ):
private void ReadFromPort()
{
string value = value from port;
if (text1.InvokeRequired)
{
Type t = text1.GetType();
MethodInfo info = t.GetProperty("Text").GetSetMethod();
Delegate d = Delegate.CreateDelegate(t, info);
text1.Invoke(d, new object[] {value});
}
else text1.Text = value;
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Keeping in mind that was example code, FYI that snippet won't work; Delegate.CreateDelegate takes a Type parameter for delegate types only. You might want to try this instead:
private delegate void SetTextDelegate(TextBox tb, string text);
private void ReadFromPort(TextBox tb)
{
string portData = ...
this.SetText(tb, portData);
}
private void SetText(TextBox tb, string text)
{
if(tb.InvokeRequired)
{
tb.Invoke(new SetTextDelegate(SetText), new object[] {tb, text});
}
else tb.Text = text;
}
I *think* that should work.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
thx for the help guys appreciate it
|
|
|
|
|
Hi Lao.
Thank you for you help.
But, the thread method is the method that read the comm. port, so can I pass a parameter to it?, a parameter like TextBox tb?.
That method is in another class, no in the class that holds the textbox, and should I pass every control as parameter that I want to write, (with data from the comm port)?.
Thank you again for your time.
Demian.
|
|
|
|
|
The code works fine.
But I must pass a textbox reference to the class constructor. And this is a very particular case, 'cause I don't know how many controls I will have, to show the data that the thread read from the comm port.
Thank you Judah.
Demian.
|
|
|
|
|
This is only if your thread method is in a different class. More than likely, there's no need to do that. In both Judah's and my examples, we assumed the method that will be invoked in another thread was part of the same class, so it already has a reference to the TextBox . This is preferred unless you have some good reason for changing it. If you do, then create a new instance of another class - passing the TextBox reference into the constructor - and start a thread on a method of that class. This is unnecessary, though, because you're creating another class just to run a method in another thread? Why go to the trouble if you don't have to.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi!
Well, I have a class hierarchy, and theses classes must keep a communication "alive" with a devices pluged in the comm port. The device, if it has no heceived a command stop the communication.
That is the trouble, the thread method is a method deep int the hierarchy.
Thank you for your time.
Demian.
|
|
|
|
|
Like I said, then, either pass the TextBox reference into the class's constructor or set a property before you start the thread on a method of that class.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi.
Yes, that works, but there's no relation between the classes hierarchy and a control as reference in a constructor or in a property.
Theses are communication protocol classes, it's so weird to find a control reference in their definitions. I loss the essence of the class hierarchy just putting a textbox in the definitions.
That's the problem.
Thank you very much for your feedback.
Demian.
|
|
|
|
|
Hello masters,
I have done a simple application in C# where I simply create a new UserControl derived class that draws a diagonal a red line on a blue background.
I have used some techniques used in C++ to avoid flickering, but when I resize my dialog box that contains my control, the drawing awfuly flickers.
How can I avoid flickering drawings?
I do the following thing:
<br />
internal sealed class Tetrion : UserControl<br />
{<br />
private GameBoard m_gameBoard=new GameBoard();<br />
<br />
internal Tetrion()<br />
{<br />
Debug.WriteLine("Tetrion.Tetrion");<br />
SetStyle(ControlStyles.DoubleBuffer, true);<br />
}<br />
<br />
public void Draw(Object sender, PaintEventArgs e)<br />
{<br />
Debug.WriteLine("Tetrion.OnPaint");<br />
m_gameBoard.Draw(e.Graphics, ClientRectangle);<br />
}<br />
<br />
protected override void OnResize(EventArgs e)<br />
{<br />
base.OnResize(e);<br />
Invalidate();<br />
}<br />
}<br />
I have registered the Draw event in the MainForm's constructor class like this:
<br />
m_tetrion.Paint+=new PaintEventHandler(m_tetrion.Draw);<br />
and, at last, the Draw method of the GameBoard class looks like this:
<br />
public void Draw(Graphics graphics, Rectangle rect)<br />
{<br />
Debug.WriteLine("GameBoard.Draw");<br />
<br />
Bitmap bmp=new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);<br />
Graphics memGraphics=Graphics.FromImage(bmp);<br />
Pen pen=new Pen(Color.Red);<br />
<br />
SolidBrush brush=new SolidBrush(SystemColors.Control);<br />
memGraphics.FillRectangle(brush, rect);<br />
<br />
memGraphics.DrawLine(pen, rect.X, rect.Y, rect.Width, rect.Height);<br />
<br />
graphics.DrawImage(bmp, rect);<br />
}<br />
I think everything looks fine to me in the code, but it still flickering...
Please, help!
Thanks!!!
|
|
|
|
|
According to the documentation for ControlStyles.DoubleBuffer , you must also set ControlStyles.UserPaint and the ControlStyles.AllPaintingInWmPaint to true also for double buffering to work properly. For example
this.SetStyle(ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true);
If you're going to be doing ~all~ the painting, don't use a UserControl. Instead you'll want to write a custom control: just create a class an inherit directly from System.Windows.Forms.Control class. Visual Studio has a template for this, Project->Add Class->Custom control.
---------------------------
He who knows that enough is enough will always have enough.
-Lao Tsu
|
|
|
|
|
Thanks a lot Judah!!!
It works great that way. it does not flickers anymore!
|
|
|
|
|
In addition to what Judah said, using Debug.WriteLine in drawing code is NOT recommended. The TraceListener s (both Debug and Trace use them, which are compiled to code if the DEBUG and/or TRACE pre-proc defs are defined at compile time) are very slow. When you debug this application, it gets even slower since the DefaultTraceListener uses the native OutputDebugString which VS.NET catches and displays in your output window - this is a blocking call (i.e., your drawing code is foregone until that process described above is complete).
If all you had was the Debug.WriteLine and did a default Release compile, it wouldn't be included, but there's really no reason to trace this call anyway. It either works or it doesn't, and this will only slow it down. If you're painting your control, you'll notice if it works and you don't need a trace statement for that.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi,
Thanks for the answers. If I included traces in the Drawing procedure, it's because I want to know if it does not call too many times. Then I see that when I resize my dialog box, the drawing function is called only once. But even in Release, it's still flicker with or without the trace calls.
|
|
|
|
|
I'm just sayin'...
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
After applying Judah's modification, when I have debug traces it slows down, but it does not flicker. In release, it runs smoothly C# is cool!
|
|
|
|
|
By the way,
In C#, I don't see any differences between these two drawing techniques (both are smooth):
- creating the image in a memory bitmap then display it once the bitmap is done,
- directly draw on the graphic's context (DC) without using a memory bitmap
Both are smooth. I guess it's because of the SetStyle call.. right?
In MFC/Win32, when you draw directly on the DC, it flickers, that's why you need to create the image in memory, and once done, you display it. in C#, wether or not the bitmap is built in memory, there is no flickering
Best regards.
|
|
|
|
|
bouli wrote:
I guess it's because of the SetStyle call.. right?
Most likely. If you specify the right flags for double-buffering, the OnDraw is probably called in a different thread (or buried deep in implementation) and once finished the image is drawn to the DC (or flipped). I haven't looked into it that deep.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
how can i encrypt the output of my program using the 128 bit encrypt algorithm?
|
|
|
|
|
System.Security.Cryptography implements a whole bunch of ways to encrypt look in the encryption part of this site: CP on Cryptograhpy
|
|
|
|
|