|
I am just starting to learn about creating custom controls using the book "GDI+ Custom Controls with Visual C# 2005". I am a little confused about overriding the control's OnPaint function. As a test, I created a custom control that has just a label. I then created the following code:
protected override void OnPaint(PaintEventArgs e)
{
}
I figured that since I am not calling the base.OnPaint(e), that the label would not get displayed, however when I run this, the label still shows up. Can someone explain why overriding a custom control and not calling base.OnPaint(e) does not effect and controls that are part of the custom control?
|
|
|
|
|
When you create a label control, a new window is created and as every window it's receiving it's own messages from the main message loop, including the paint message. A method Label.OnPaint is not invoked from the UserControl.OnPaint . It's called by Control.WmPaint(ref Message m) , which is called by (...), which is called by Application.ThreadContext.RunMessageLoop(int reason, ApplicationContext context) .
Try to make a "user control", which derives from Label , like this:
class MyControl : Label
{
...
override OnPaint { }
}
Then the label will not be drawn.
Greetings - Gajatko
Portable.NET is part of DotGNU, a project to build a complete Free Software replacement for .NET - a system that truly belongs to the developers.
|
|
|
|
|
Hi, i got a Main form which is called FrmMain and the IsMDIContainter is set to true;
When the application is executed, the Form_load i got this code
FrmLogin childLogin = new FrmLogin();
childLogin.ShowDialog(this);
and my constructor i got
public FrmMain()
{
InitializeComponent();
allData = new AllData();
}
this is my AllData.cs
public class AllData
{
private Hashtable ht;
public AllData()
{
ht = new Hashtable();
}
}
Inside my FrmLogin constructor i got
public FrmLogin()
{
InitializeComponent();
staff = new Staff("Admin", "S123456I", "pass123", "13 April 1988", "ADDRESS", 91234567, 61234567, true, true, false, true);
}
how do i add the staff to my hashtable which is declare in the main form?
|
|
|
|
|
|
Inside my FrmMain (parent)
I have this
public Hashtable staffTable;
public FrmMain()
{
InitializeComponent();
staffTable = new Hashtable();
}
And inside my FrmLogin (child)
private FrmMain ParentForm;
private Staff staff;
public FrmLogin()
{
InitializeComponent();
staff = new Staff("Admin", "S123456A", "pass123", "13 April 1988", "ADDRESS", 912346678, 12345678, true, true, false, true);
((FrmMain)ParentForm).staffTable.Add("S8812466I", staff);
}
When the application is run, i get this error
"NullReferenceException was unhandled"
Object reference not set to an instance of an object.
modified on Sunday, July 6, 2008 6:26 AM
|
|
|
|
|
In FrmLogin create a delegate/event/event method, and a public class that inherits from EventArgs. In FrmMain, after FrmLogin is insanciated (but before it's shown), subscribe to the event in FrmLogin. Then, FrmLogin can raise the event and pass the Staff object in the eventargs, which will be received by FrmMain because it's listening for it.
Dave
|
|
|
|
|
Omg. erm i am new to C#, can u make it a little simpler?
probably u can give me some example?
modified on Sunday, July 6, 2008 7:48 AM
|
|
|
|
|
There's plenty of examples around - I've coded up a quick one below (needs much improvement but a starter).
frmMain:
using System;
using System.Windows.Forms;
namespace EventSample
{
public partial class frmMain : Form
{
public frmMain()
{
InitializeComponent();
}
private void frmMain_Shown(object sender, EventArgs e)
{
frmLogin loginForm = new frmLogin();
loginForm.StaffLogin += new OnStaffLogin(loginForm_StaffLogin);
loginForm.ShowDialog();
loginForm.Dispose();
}
void loginForm_StaffLogin(object sender, LogInEventArgs e)
{
MessageBox.Show("Staff logged in: " + e.Staff.Name);
}
}
public class Staff
{
private string m_Name;
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
public Staff(string name)
{
m_Name = name;
}
}
}
frmLogin (with button1 added):
using System;
using System.Windows.Forms;
namespace EventSample
{
public delegate void OnStaffLogin(object sender, LogInEventArgs e);
public partial class frmLogin : Form
{
public event OnStaffLogin StaffLogin;
public frmLogin()
{
InitializeComponent();
}
private void FireStaffLogin()
{
StaffLogin(this, new LogInEventArgs(new Staff("Staff name goes here!")));
}
private void button1_Click(object sender, EventArgs e)
{
if (StaffLogin != null)
{
FireStaffLogin();
}
Close();
}
}
public class LogInEventArgs : EventArgs
{
private Staff m_Staff;
public Staff Staff
{
get { return m_Staff; }
set { m_Staff = value; }
}
public LogInEventArgs(Staff staff)
{
m_Staff = staff;
}
}
}
Dave
|
|
|
|
|
why does it look so complicated. LOL.. okay i show u more of my code probably u got a simpler way.
FrmMain
namespace EBMS
{
public partial class FrmMain : Form
{
public Hashtable staffTable;
public FrmMain()
{
InitializeComponent();
staffTable = new Hashtable();
}
private void FrmMain_Load(object sender, EventArgs e)
{
this.toolStripStaff.Visible = false;
this.toolStripCatalogue.Visible = false;
this.toolStripOrder.Visible = false;
this.toolStripInventory.Visible = false;
this.toolStrip.Enabled = false;
FrmLogin childLogin = new FrmLogin();
childLogin.ShowDialog(this);
if (childLogin.DialogResult == DialogResult.OK)
{
this.toolStripStaff.Visible = true;
this.toolStripCatalogue.Visible = true;
this.toolStripOrder.Visible = true;
this.toolStripInventory.Visible = true;
this.toolStripLogin.Visible = false;
this.toolStrip.Enabled = true;
stripLblLoginAs.Text = "Login As : " + childLogin.Username;
}
}
as u can see inside the constructor of FrmMain(), i have created an instance of the hashtable called 'staffTable'
FrmLogin
namespace EBMS
{
public partial class FrmLogin : Form
{
public FrmMain ParentForm;
private Staff staff;
public FrmLogin()
{
InitializeComponent();
staff = new Staff("Admin", "S123456I", "pass123", "13 April 1988", "address", 12345678, 12346567, true, true, false, true);
((FrmMain)ParentForm).staffTable.Add("S123456I", staff);
}
as u can see my FrmLogin last line of code, it will call the instance (staffTable) that is created in FrmMain when it loaded
Staff.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace EBMS
{
public class Staff
{
private string name;
private string nric;
private string password;
private string dob;
private string address;
private uint mobile;
private uint home;
private bool catManager;
private bool inventManager;
private bool orderManager;
private bool administrator;
public Staff(string name, string nric, string password, string dob,
string address, uint mobile, uint home, bool catManager, bool inventManager,
bool orderManager, bool administrator)
{
this.name = name;
this.nric = nric;
this.password = password;
this.dob = dob;
this.address = address;
this.mobile = mobile;
this.home = home;
this.catManager = catManager;
this.inventManager = inventManager;
this.orderManager = orderManager;
this.administrator = administrator;
}
public string Name
{
get { return name; }
}
public string NRIC
{
get { return nric; }
}
public string Password
{
get { return password; }
}
public string DOB
{
get { return dob; }
}
public string Address
{
get { return address; }
}
public uint Mobile
{
get { return mobile; }
}
public uint Home
{
get { return home; }
}
public bool CatManager
{
get { return catManager; }
}
public bool InventManager
{
get { return inventManager; }
}
public bool OrderManager
{
get { return orderManager; }
}
public bool Administrator
{
get { return administrator; }
}
}
}
|
|
|
|
|
I'm watching the F1 grand prix at the moment - will have a look at your code afterwards!
Dave
|
|
|
|
|
Doing it this way, the only way is to pass the hashtable to FrmLogin by overloading the constructor
FrmLogin:
private Hashtable staffTableFromMain;
public FrmLogin(Hashtable staffTable)
{
InitializeComponent();
staffTableFromMain = staffTable;
} You can then add to the table (as it's passed by reference) directly from fmLogin.
Edit: You'll need to change the line where you create the instance of FrmLogin in FrmMain as well of course!
FrmLogin childLogin = new FrmLogin(staffTable);
It's not the best way though. FrmLogin has no need to know about the staff table and really shouldn't be altering it. Also, imagine if there were other objects apart from frmMain that needed to know that the staffTable had changed... you would have no way to inform them. Thats's what events are for.
Examine the code I gave you before and read up on custom Events and Delegates. It is a far better way to do it and no so difficult when you get your head around it.
Dave
modified on Sunday, July 6, 2008 10:26 AM
|
|
|
|
|
the code u gave me before can be done??
could you give me 1 example based on my code? so sorry to trouble you..
why cant i just cast it to mainform then get the staffTable from there? thought it should work?
modified on Sunday, July 6, 2008 10:56 AM
|
|
|
|
|
benjamin yap wrote: why cant i just cast it to mainform then get the staffTable from there? thought it should work?
Casting will create a new instance so you won't be able to access the original.
Options:
1. Send the hashtable to the other form in FrmLogin constructor so it can be modified.
2. Send the FrmMain to FrmLogin in FrmLogin constructor so all objects of the FrmMain object instance can be accessed/modified - similar to number 1.
3. Make FrmLogin raise an event - preferred.
I've based this on your code as requested but it doesn't exactly make sense this way as I couldn't properly figure out your code flow - a staff member is added to the staff table in the FrmLogin contructor??? Anyway... here is a working sample. Again I've added a button to the frmLogin and the hardcoded staff is added there. Staff class remains unchanged.
FrmMain:
namespace EBMS
{
public partial class FrmMain : Form
{
public Hashtable staffTable;
public FrmMain()
{
InitializeComponent();
staffTable = new Hashtable();
}
private void frmMain_Load(object sender, EventArgs e)
{
FrmLogin childLogin = new FrmLogin();
childLogin.StaffChange += new OnStaffChange(childLogin_StaffChange);
childLogin.ShowDialog(this);
childLogin.Dispose();
}
void childLogin_StaffChange(object sender, StaffChangeEventArgs e)
{
staffTable.Add(e.Staff.NRIC, e.Staff);
MessageBox.Show("Added " + e.Staff.NRIC + " to table.");
}
}
}
FrmLogin:
namespace EBMS
{
public delegate void OnStaffChange(object sender, StaffChangeEventArgs e);
public partial class FrmLogin : Form
{
public event OnStaffChange StaffChange;
public FrmLogin()
{
InitializeComponent();
}
private void FireStaffChange(Staff staff)
{
if (StaffChange != null)
{
StaffChange(this, new StaffChangeEventArgs(staff));
}
}
private void button1_Click(object sender, EventArgs e)
{
Staff staff = new Staff(
"Admin",
"S123456I",
"pass123",
"13 April 1988",
"address",
12345678,
12346567,
true,
true,
false,
true);
FireStaffChange(staff);
Close();
}
}
}
StaffChangeEventArgs:
namespace EBMS
{
public class StaffChangeEventArgs : EventArgs
{
private Staff m_Staff;
public Staff Staff
{
get { return m_Staff; }
set { m_Staff = value; }
}
public StaffChangeEventArgs(Staff staff)
{
m_Staff = staff;
}
}
}
Dave
|
|
|
|
|
oh oh i forgot to tell you that the user is created in the constructor because i want it to automatically create a default user first. thats why i added it in the constructor.
btw, where do i add this code
namespace EBMS{
public class StaffChangeEventArgs : EventArgs
{
private Staff m_Staff;
public Staff Staff
{
get { return m_Staff; }
set { m_Staff = value; }
}
public StaffChangeEventArgs(Staff staff)
{
m_Staff = staff;
}
}
}
modified on Sunday, July 6, 2008 12:13 PM
|
|
|
|
|
anywhere! Create a new class and simply call it StaffChangeEventArgs then overwrite with this code
Dave
|
|
|
|
|
I've been thinking about this a little more...
In this case it seems that the staffTable is really the link between the two forms (and maybe others too?). If it is, maybe you should create a static class and create the staffTable as public static in there.
Doing it this way, it will accessible to both the FrmMain and FrmLogin, and you could create any events required in the staffTable... then, when the FrmLogin alters the staffTable - the staffTable can raise the event which you can make FrmMain listen for and react accordingly. A much better way!
Dave
|
|
|
|
|
Omg means i got to create alot different class? because i still have Product hastable, catalogue hashtable, order hashtable and a few more..
So u mean create a new class for example AllData.cs
Then inside , i put the attriubutes as
public static Hashtable staffTable;
public static Hashtable productTable;
public static Hashtable orderTable;
then for the constructor
public AllData()
{
staffTable = new Hashtable();
productTable = new Hashtable();
orderTable = new Hashtable();
}
Then inside my FrmMain i create a new AllData class?
FrmMain.cs
public AllData allData;
public FrmMain()
{
allData = new AllData();
}
Then from the child form, how do i access this allData created in the FrmMain
|
|
|
|
|
There's no need to cretae an instance of the AllData class if the contents are static.
public static class AllData
{
public static Hashtable staffTable = new Hashtable();
public static Hashtable productTable = new Hashtable();
public static Hashtable productTable = new Hashtable();
}
You can then simply call AllData.staffTable from any class in the same namespace, or specify the namespace as well if not.
Dave
|
|
|
|
|
Thanks davey
I use the constructor method and pass the hashtabble
|
|
|
|
|
I have a combobox that is bound to the database. When I update this combobox, selected value changes.
Let's say that we have these values in combobox: AAA, BBB, CCC. The selected value is CCC. When the combobox
is updated, the selected value changes to AAA. It always changes to the first item in combobox.
Does anyone have any idea how to solve this?
Thanks
|
|
|
|
|
Hi, I am new to C# and im working trying some image processing, im using this bit of code to invert the pixels on an image grabbed from a video file, how do I extract the RGB values from a pixel in C# using the image buffer? Speed is of the essence...
Thanks in advance.
unsafe
{
byte* p = (byte *)(void *)pBuffer;
int nWidth = Width * 3;
for(int y = 0; y < Height; y++)
{
for(int x = 0; x < nWidth; x++ )
{
p[0] = (byte)(255-p[0]);
p++;
|
|
|
|
|
See this article[^], there are some examples how to extract and modify the RGB values of an image.
regards
modified 12-Sep-18 21:01pm.
|
|
|
|
|
This is how you get the color components of a pixel, specified by the x and y coordinates:
byte* p = (byte *)(void *)pBuffer;
p += (x + y * Width) * 3;
byte r = *(p++);
byte g = *(p++);
byte b = *p;
If you increase the pointer for the last component also, it will point to the next pixel. This is very useful if you access the pixels in sequence, as you don't have to calculate a new address for each pixel.
Despite everything, the person most likely to be fooling you next is yourself.
|
|
|
|
|
Hi All,
I have a field that I which to filter on using the Contains operator but currently its throwing a wobbly. Can anyone advise? Is this even a legal operator to use in the DataView?
filter = filter + "and fileName Contains '" + _freetext.ToString() + "'";
fileName is of type string. For instance the _freetext maybe something like "day" so things like "daytime", "sunday" would both be included.
Thanks in advance.
Jammer
Going where everyone here has gone before!
My Blog
|
|
|
|
|
Hi..
I deployed my widows project successfully( included SQL express, .net frame work, Database file, Project files)
I installed my .exe file (setup file) on client machine(system) its installed successfully.
But when i run that application ,i got the below error:
============================
Login failed for user 'sa'. The user is not associated with a trusted SQL Server connection.
<configuration>
<system.windows.forms jitDebugging="true"/>
</configuration>
When JIT debugging is enabled any unhandled exception will be sent to the JIT debugger registered on the computer rather than be handled by this dialog box.
=============================
please help me...
thanks in advance
|
|
|
|
|