|
Don't call it "OnPaint" - that has a specific meaning, you will find out later and don't need to worry about that now.
using System.Drawing;
using System.Windows.Forms;
public partial class ECGMachine
{
...
public void Paint(Graphics g)
{
g.FillRectangle(Brushes.Red, g.ClipBounds);
}
...
}
Replace the FillRectangle with your code...
Then in to OnPaint method for your user control / panel as previously:
...
myECGMachineINstance.Paint(e.Graphics);
...
[edit]I forgot to tell you how to call it... blame lack of coffee.[/edit]
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
OK I got that to work, however...
Once I have created the control, instead of coding its position, size etc I would like to manualy draw a panal object on the form, so how would I then "atach" the new panal to my control?
Thank you
Steve
|
|
|
|
|
Sorry for the delay - bloody work gets in the way sometimes: I mean, just because they pay you...
I'm not exactly sure what you mean. Why do you want to:
stephen.darling wrote: manualy draw a panal object on the form
and then
stephen.darling wrote: how would I then "atach" the new panal to my control
If you mean "I want to put a new panel on my form in software, rather than the designer, and then put my new control on that panel" then:
Panel p = new Panel();
p.Location = pointIWantMyPanel;
p.Size = sizeIWantMyPanel;
Controls.Add(p);
MyECGDisplayControl myECG = new MyECGDisplayControl();
myECG.Location = pointIWantMyECG;
myECG.Size = sizeIWantMyECG;
p.Controls.Add(myECG);
But to be honest you don't need the panel for that - your control can act as the panel if it is derived from Panel or UserControl.
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.
|
|
|
|
|
Dear All,
I have list of date ranges (Start Date and End Date). I want to find the gap between the each item. ie;
My date range list
#. Start Date End Date
1. 1-Jan-2010 2-Jan-2010
2. 1-Jan-2010 8-Jan-2010
3. 4-Jan-2010 4-Jan-2010
4. 6-Jan-2010 8-Jan-2010
5. 9-Jan-2010 10-Jan-2010
6. 10-Jan-2010 14-Jan-2010
7. 10-Jan-2010 15-Jan-2010
8. 17-Jan-2010 18-Jan-2010
Actually i want to get the gap between adjacent items.
Expected output
GapStart GapEnd
16-Jan-2010 16-Jan-2010
But i get the following
GapStart GapEnd
05-Jan-2010 05-Jan-2010 (Not need this gap because many other items include this date range)
16-Jan-2010 16-Jan-2010
How can i filter the resultant list?
Regards,
Lalk
|
|
|
|
|
And how are you doing it right now?
I would create a dictionary (Dictionary<DateTime, bool> dates ) and fill it with all dates, that are available (in your example I would put there all dates between 1-Jan-2010 and 18-Jan-2010). Next there would be a loop over all ranges, and in this loop second loop over all dates in range. And I would set dates[currentDate] to true (where currentDate is date, that is pointed by double loop.
After those loops you have a dictionary, where false is set on dates, that aren't in any of the ranges.
Hope you get the idea.
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
If u don't mind, could u please post the code scrap here.
I am using two loops and finding the difference between each date range (currentItem.StartDate - prevItem.EndDate). Then checking it with all the date renages.
|
|
|
|
|
<code>Dictionary<DateTime, bool> dates = new Dictionary<DateTime, bool>();
for(DateTime loop = Min(ranges); loop < Max(ranges); loop = loop.AddDays(1))
{
dates.Add(loop, false);
}
for(int i = 0; i < ranges.count; i++)
{
for(DateTime loop = ranges[i].Start; loop < ranges[i].End; loop = loop.AddDays(1))
{
dates[loop] = true;
}
}
Min(ranges) and Max(ranges) give minimal and maximal range start (you must create them yourself). Rest of the code should compile and work, but I didn't check them.
You will find gaps, where dates[some date] is false.
Don't forget to rate answer, that helped you. It will allow other people find their answers faster.
|
|
|
|
|
Thanks Nowakowski. Its working fine..
|
|
|
|
|
I have simple list with point.
I need to return new list with all point that their X value is 50 -
The code :
The compile error that i get is
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<System.Drawing.Point>' to 'System.Collections.Generic.List<System.Drawing.Point>'. An explicit conversion exists (are you missing a cast?)
public static List<Point> SelectX<T>( this List<Point> PointCollection)
{
List<Point> pointCollectionSelected = new List<Point>();
pointCollectionSelected = from i in PointCollection
where i.X == 50
select i;
return pointCollectionSelected;
}
What i did wrong ?
|
|
|
|
|
Yanshof wrote: pointCollectionSelected = from i in PointCollection where i.X == 50
select i;
pointCollectionSelected = (from i in PointCollection
where i.X == 50
select i).ToList();
I have CDO, it's OCD with the letters in the right order; just as they ruddy well should be Forgive your enemies - it messes with their heads
My blog | My articles | MoXAML PowerToys | Onyx
modified on Tuesday, September 21, 2010 4:25 AM
|
|
|
|
|
Not that it answers your question, but...
0) What are you doing with the generic parameter (T)?
1) Why are you initializing pointCollectionSelected?
|
|
|
|
|
Hi All,
I need to add rows to a datagridview programaticcaly. The data in the datagridview is loaded from an xml file. I could find out by googling that, for adding data to gridview we need to add data to the dataset and refresh the datagridview. But how can I get the data from the datagridview into a dataset? how to accomplish this. Please help.
Thanks in adavance.
modified on Wednesday, September 29, 2010 8:20 AM
|
|
|
|
|
Hi,
I use the following function to take an array of points (an ECG graph) and draw it onto a panal.
I have a timer to tick at 500ms
I then call Invalidate in the timer
The graph does indeed draw the expected ECG graph, but it draws a random, ugly straight line near the bottom of the graph and sometimes at the top, and I cannot seem to figure out why?
private void ecgDisplay_Paint(object sender, PaintEventArgs e)
{
for (int i = 0; i < ECGArray.Length; i++)
{
if (x > ecgDisplay.Width) x = 0;
x += 1;
p = 80 - (ECGArray[i] / 6 + 50);
e.Graphics.DrawLine(yelgpen, px, pp + 30, x, p + 30);
e.Graphics.DrawRectangle(blackpen, 0, 0, x + 1, ecgDisplay.Height);
pp = p;
pq = q;
pr = r;
px = x;
}
}
i am using doublebuffering also.
Does anyone know what might be going on?
thank you
Steve
|
|
|
|
|
Hi Steve,
1.
are you and "Member 7455306" one and the same? there is another ECG thread on this page! It is getting confusing...
2.
I can't tell for sure what is right or wrong in the code shown as there are a lot of magic constants which may or may not be OK.
3.
the x your code is using is probably ranging from 1 to ecgDisplay.Width+1 inclusive, so you are not having it point into the first column (x=0), and it is pointing in two columns that are beyond the ecgDisplay (width, and width+1).
4.
if and when x wraps back to 1, there will emerge a backward line from px=width+1 to x=1 which is probably the thing you see and don't like.
5.
a potential problem: if ECGArray would be partially filled, i.e. contain fewer than ECGArray.Length actual values, the remainder would be zero, and also get plotted.
6.
I find your erasure strategy a bit weird; instead of
e.Graphics.DrawRectangle(blackpen, 0, 0, x + 1, ecgDisplay.Height);
I would go along this line (the hor coordinate may be off by 1):
e.Graphics.DrawLine(blackpen, x+1, 0, x + 1, ecgDisplay.Height-1);
That's it for now.
|
|
|
|
|
this is on mobile app
panel4 = visible and doc = fill
panel4.controls.clear = done before this
Button dynamicButton = new Button();<br />
dynamicButton.Name = "dynamicButton" + i.ToString();<br />
dynamicButton.Width = 75;<br />
dynamicButton.Height = 23;<br />
dynamicButton.Left = left;<br />
dynamicButton.Top = 10 + (dynamicButton.Height * i) + (10 * i);<br />
dynamicButton.Text = valuename.ToString();<br />
dynamicButton.Click += new EventHandler(Button_Click);
panel4.Controls.Add(dynamicButton);
but the controls won't show up what i'am doing wrong
thanks
|
|
|
|
|
I suggest you check the value of left .
Also not sure what i would be, so Top too could be wrong.
|
|
|
|
|
panel4.Controls.Clear();<br />
Application.DoEvents();<br />
int i = 0;<br />
int left = 9;<br />
waarb = @"Comm\ConnMgr";<br />
RegKey = Registry.LocalMachine.OpenSubKey(waarb);<br />
<br />
if (RegKey != null)<br />
{<br />
foreach (string valuename in RegKey.GetSubKeyNames()) <br />
{<br />
Button dynamicButton = new Button();<br />
dynamicButton.Name = "dynamicButton" + i.ToString();<br />
dynamicButton.Width = 75;<br />
dynamicButton.Height = 23;<br />
dynamicButton.Left = left;<br />
dynamicButton.Top = 10 + (dynamicButton.Height * i) + (10 * i);<br />
dynamicButton.Text = valuename.ToString();<br />
dynamicButton.Click += new EventHandler(Button_Click);
panel4.Controls.Add(dynamicButton);<br />
Application.DoEvents();<br />
i++;<br />
}<br />
RegKey.Flush();<br />
RegKey.Close();<br />
}<br />
Application.DoEvents();<br />
}
|
|
|
|
|
Hi,
1.
if you were to use PRE tags instead of CODE tags, formatting would have been preserved resulting in better readability.
2.
My (non-mobile) system doesn't have a registry key HKLM\Comm.
If yours doesn't either, no buttons would show.
3.
I see several Applications.DoEvents() , and they in general are evil. As I don't know where the code shown resides, I can't start to explain how dangerous they could be.
4.
I have no idea why you call RegKey.Flush(); on a key that was opened for reading.
5.
if #2 doesn't solve your immediate problem, I suggest you debug, i.e. look at intermediate values, by adding log statements and/or single-stepping.
|
|
|
|
|
1 true
2 on my first post it says "this is on mobile"
3 t'is was put in for a last solution
4 t'is was a code block that i copyed from somwher else
5 all the things you say are things nothing to do with the problem
if i do a control count on the panel they are there , but don't show
yes i have use visibel, enable,show,... nothing seems to help
and it's late in the morning "don't turn around the cookingpan"
just tested
if i use the form itself for the controls no problem
controls.add(..) works
panel4.controls.add(..) don't work
modified on Monday, September 20, 2010 11:26 PM
|
|
|
|
|
Make sure that panel4 is actually visible and the topmost control on the view stack (zorder is appropriate).
The funniest thing about this particular signature is that by the time you realise it doesn't say anything it's too late to stop reading it.
My latest tip/trick
Visit the Hindi forum here.
|
|
|
|
|
Try to get rid of your Application.DoEvent() first.
It's better to surround the creation of your controls by SuspendLayout() /ResumeLayout() .
panel4.Controls.Clear();
int i = 0;
int left = 9;
waarb = @"Comm\ConnMgr";
RegKey = Registry.LocalMachine.OpenSubKey(waarb);
if (RegKey != null)
{
Button dynamicButton = null;
this.SuspendLayout();
foreach (string valuename in RegKey.GetSubKeyNames())
{
dynamicButton = new Button();
dynamicButton.Name = "dynamicButton" + i.ToString();
dynamicButton.Width = 75;
dynamicButton.Height = 23;
dynamicButton.Left = left;
dynamicButton.Top = 10 + (dynamicButton.Height + 10) * i;
dynamicButton.Text = valuename.ToString();
dynamicButton.Click += new EventHandler(Button_Click);
panel4.Controls.Add(dynamicButton);
i++;
}
this.ResumeLayout();
RegKey.Flush();
RegKey.Close();
}
Then debug your application :
Put a spy on the panel4 object.
See the Controls property of panel4. What's in there ? Does the Count property seem correct (i.e. it has the same as the number of keys in the registry).
Then put a beakpoint in your loop. For each button created, check its properties ; maybe there's one you didn't think of and that has to be set.
|
|
|
|
|
Hello everyone,
Could someone please assist with the following problem?
I have an ecgMachine class that handles (or will) the drawing of an ECG graph onto a picture box.
I have my main form, with a picture box called ecgDisplay on it.
When the simulation starts, depending on the patient data loaded (from a file) the timer starts, and every n miliseconds I need to draw/update the picturebox.
Now my problem is this as I am still confused.
Do I a) create and pass in a picturebox object from the form to the ecg class,
or B) get an ecg object into the main form and handle drawing in there?
Any advice would be great, and to just clarify, the following is a function that will be used to actualy draw the ecg...
(ecgDisplay = the pictureBox)..
private void drawEcg()
{
const int scaleX = 40;
const int scaleY = 40;
Point ecgDisplayTopLeft = new Point(0, 0);
Point ecgDisplayTopLeftMinus1 = new Point(-1, 0);
int halfX = ecgDisplay.Width / 2;
int halfY = ecgDisplay.Height / 2;
Size size = new Size(halfX + 20, ecgDisplay.Height);
Graphics g = ecgDisplay.CreateGraphics();
g.TranslateTransform(halfX, halfY);
g.ScaleTransform(scaleX, scaleY);
g.Clear(Color.Black);
g.ResetClip();
float lastY = (float)Math.Sin(0);
float y = lastY;
Pen p = new Pen(Color.White, 0.01F);
float stepX = 1F / scaleX;
for (float x = 0; x < 10; x += stepX)
{
}
}
Thank you
Steve
|
|
|
|
|
Hi Steve,
I have several comments:
1.
PictureBox is a pretty stupid Control capable of showing an existing image. As soon as something more complex is required (such as scaling the picture AND painting a capture rectangle on top of it), it becomes a real pain.
As you are not taking advantage of the few actual PictureBox capabilities, you'd better not use one at all. A simple Panel also can be drawn upon.
2.
Whatever Control you choose, in WinForms all drawing should occur in the Paint handler, and CreateGraphics is to be avoided. You may want and read this little article[^].
3.
You may also be interested in this thread[^], where something similar is going on. I will add messages in that thread later on.
[ADDED]
And I forgot to answer some questions:
you do not pass the PictureBox (or any other GUI thing) to the ECG class; the ECG class represents an ECG, and is not interested in your current way of viewing an ECG. You may choose a different view later on, which would cause the ECG class to need changes.
The correct way would be to provide the new data (an ECG object) to your viewer, which is either your current app's Form, or some specialized Control, maybe an instance of some EcgViewer class, which could derive from UserControl. If your viewer isn't a specialized viewer, then it would not understand ECG objects, and what you pass from one to the other has to be dumbed down, maybe just a Bitmap could do. Or you could create an Interface, that is a contract between producers (such as ECG) and consumers (such as your viewer).
If your data is dynamic (i.e. rather than passing a full ECG or a full image, you pass a life something), then your app fits the requirements mentioned in the link I provided.
[/ADDED]
|
|
|
|
|
I have been reading up on WPF for two weeks now (Specifically using the MVVM pattern) and I am having a very tough time grasping it. Maybe it is the complete abstract nature of the literature that makes it confusing, but I am not sure. I have been retooling a Winforms application in WPF and I am running into the total monotony of wrapping all of my data elements. Am I missing something here? From what I have read by data wrapper (Model) is a wrap for every field in the database that I am going to work with. And I have to write my own save methods, delete methods, etc... ?
Isn't this what the Winforms dataset object does? I have seen some writing about the INotifyProperty interface, but I have not found a good explanation of it or rather a good example.
I am not a formally trained programmer, so some of the more esoteric topics elude me so please forgive my ignorance on this matter.
Cheers, EA
|
|
|
|
|
Design patterns that relate to the presentation of data - MVC/MVP/MVVM - are about understanding what behavior to put in which classes so as to make your application simpler, more reliable and easier to maintain / extend.
I recommend that you google "Separation of Concerns" to get some further insight into the value of making sure any given class is focused on implementing a well defined part of the behavior of your application. This may help you understand what the MVVM books are trying to get at.
Although MVVM and the other patterns separate out the 'model' they are not asking for "unnecessary wrapping." More, they are indicating that partitioning the code that knows how to get data into and out of a database from the code that cares about what the user is trying to do with that data is a valuable thing to do.
Take a look at Linq-to-Sql, and/or the Entity Framework. Both can be used to implement the model - they provide comprehensive implementations of the CRUD operations. So you should not have to write any wrappers, nor implement your own Save, Delete, etc. methods. Guessing at what you're reading, I imagine that the book(s) is/are suggesting that you create a model that encapsulates ("abstracts away" - or - hides the details behind a simple API / interface) the work required to do the database I/O, exposing a simple API to the controller / View Model. Even if you choose to stick with DataSets, looking at how Linq-to-Sql and the Entity Framework do things will probably be instructive and useful.
HTH,
Chris
PS
Regarding INotifyPropertyChanged - it is an interface that indicates that the class implements a PropertyChanged event. Other classes can subscribe to the event to be notified when (and what) properties change. This is often used in data binding - which is a whole other topic of interest and value when building user interfaces. I recommend, when you're reading about INotifyPropertyChanged , that you also read about IEditableObject and IBindingList - which are also common in binding data objects to UI elements.
|
|
|
|
|