|
Sorry i have no clue what you are trying to explain, but thx for the quick answer.
OK, lemme explain a bit more. I have a Button control with a Borders Property. Borders is a class (see below). I would like to individually edit the properties of all Properties within Borders at DESIGN TIME.
Here's the code:
<br />
public class Border<br />
{<br />
int width;<br />
int margin;<br />
Color colorNormal;<br />
Color colorOver;<br />
Color colorDown;<br />
ButtonBorderStyle style;<br />
<br />
public Border()<br />
{<br />
width = 1;<br />
margin = 1;<br />
colorNormal = Colors.borderColorNormal;<br />
colorOver = Colors.borderColorOver;<br />
colorDown = Colors.borderColorDown;<br />
style = ButtonBorderStyle.Solid;<br />
}<br />
<br />
public ButtonBorderStyle Style <br />
{<br />
get {return this.style;}<br />
set {this.style = value;}<br />
}<br />
<br />
public int Width <br />
{<br />
get {return this.width;}<br />
set {this.width = value;}<br />
}<br />
<br />
public int Margin <br />
{<br />
get {return this.margin;}<br />
set {this.margin = value;}<br />
}<br />
<br />
public Color ColorNormal <br />
{<br />
get {return this.colorNormal;}<br />
set {this.colorNormal = value;}<br />
}<br />
<br />
public Color ColorOver <br />
{<br />
get {return this.colorOver;}<br />
set {this.colorOver = value;}<br />
}<br />
<br />
public Color ColorDown <br />
{<br />
get {return this.colorDown;}<br />
set {this.colorDown = value;}<br />
}<br />
<br />
}<br />
<br />
public class Borders<br />
{<br />
Border left;<br />
Border right;<br />
Border top;<br />
Border bottom;<br />
<br />
public Borders()<br />
{<br />
this.left = new Border();<br />
this.right = new Border();<br />
this.top = new Border();<br />
this.bottom = new Border();<br />
}<br />
<br />
public Border Left <br />
{<br />
get {return this.left;}<br />
set {this.left = value;}<br />
}<br />
<br />
public Border Right <br />
{<br />
get {return this.right;}<br />
set {this.right = value;}<br />
}<br />
<br />
public Border Top<br />
{<br />
get {return this.top;}<br />
set {this.top = value;}<br />
}<br />
<br />
public Border Bottom <br />
{<br />
get {return this.bottom;}<br />
set {this.bottom = value;}<br />
}<br />
<br />
public override string ToString()<br />
{<br />
return "Click to expand...";<br />
}<br />
}<br />
Now i would like to get that "+" sign on the propertygrid next to the Property so i can access all subitems.
Thanx
still
|
|
|
|
|
You need to implement a TypeConverter for those objects. In my screen saver application. I have an example of how to do it. Otherwise you can search MSDN for ExpandableObjectConverter you will find that there is an article with sample code on how to do it.
|
|
|
|
|
Thx will have a look
UPDATE: works great
|
|
|
|
|
You need to create a TypeConverter for your Border class then apply the System.ComponentModel.TypeConverter attribute to it.
If you look in MSDN there is a sample of a TypeConverter for the Point struct (I found it in the help topic for the TypeConverter class). In addition to what the sample implements there are two extra methods you need to implement: GetPropertiesSupported and GetProperties.
Below is the code which implements those two methods for my class Bar which contains two properties; Width and Height.
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, System.Attribute[] attributes)
{
PropertyDescriptorCollection pdc;
string[] properties;
pdc = TypeDescriptor.GetProperties(typeof(Bar), attributes);
properties = new String[2];
properties[0] = "Width";
properties[1] = "Height";
return pdc.Sort(properties);
} Good luck,
James
[Edit: That should teach me to start replying to a message *then* figure out the exact solution ]
|
|
|
|
|
Hi, no need to go thru all that for 2 properties
Code snippet of how i did it:
UPDATE: add the following line whereever u add the typeconvertor else properties wont be saved by the designer.
<br />
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]<br />
My Custom Control Class
...
<br />
[TypeConverter("System.ComponentModel.ExpandableObjectConverter")]<br />
public Borders Borders <br />
{<br />
get {return this.borders;}<br />
set <br />
{<br />
this.borders = value;<br />
}<br />
}<br />
<br />
...<br />
Then for each public Property in my class (iow Left, Right, etc) i added:
<br />
<br />
[TypeConverter("System.ComponentModel.ExpandableObjectConverter")]<br />
Use this till you get to primitive types or have Editors for the Property.
Hope this helps
PS: If you do not want the class name to appear, just override the ToString() function to something better like this:
<br />
public override string ToString()<br />
{<br />
return "Click to expand...";<br />
}<br />
or
<br />
public override string ToString()<br />
{<br />
return "Width: " + width + " Style: " + style.ToString() + " Margin: " + margin;<br />
}<br />
|
|
|
|
|
leppie wrote:
PS: If you do not want the class name to appear, just override the ToString() function to something better like this:
I think this may be the advantage that you get by implementing your own TypeConverter. If you look at many of the .NET types you can edit the one-line string version and have it update the correct values. It doesn't look like you can do that with that particular method.
Sometimes that is a nice feature to have (I commonly use it for Point, Size, and Font types) but other times it may be wasted.
I guess you go for what makes sense to implement; if you don't see the user editing the string version then your method works great; where-as for Point, Size, etc this may be the better deal because of enhanced functionality.
There is no wrong choice either way
James
|
|
|
|
|
Hey Thanx
I was looking for that answer still, gotta lot to learn still. But after reading thru it twice, i understand your point. Thanx. EG perhaps to set common properties in my case
|
|
|
|
|
How would I go about detecting if a key id down without Console.ReadLine() ... I have a while loop and want the program to stop if the user hits the "e" key, but don't want to stop the loop. I want to simple check to see if a certain combanation of keys are depressed, if they are break; if not continue.
Thanks.
|
|
|
|
|
This should do it:
protected override void OnKeyPress(System.Windows.Forms.KeyPressEventArgs e)
{
if(e.KeyChar.ToString() == "e" || e.KeyChar.ToString() == "E")
}
Nick Parker
|
|
|
|
|
|
Opps, missed that part, sorry Johnyy. Thanks for pointing that out Nish, it's been another long day.
Nick Parker
|
|
|
|
|
You can use following
while(Cosnole.Read() != 'e')
{
.
.
//Do something
.
.
}
read only reads one character at a time
|
|
|
|
|
It's my understanding that System.Console.Read() reads everything until a return (someone presses enter). That while loop stops and waits for keyboard input, I dont want that... there's got to be some way of doing this I just gotta find it.
|
|
|
|
|
One option is to have a thread that reads the keyboard and have it change the value controlling the while loop when the key you want is pressed.
/ So code could be something like this…
static void Main(string[] args)
{
bool bLoop = true;
YourThreadedClass ytc = new YourThreadedClass(ref bLoop);
ytc.Start();
while(bLoop)
{
}
}
Unfortunately I’m new to C# so haven’t had chance to look at creating threaded classes yet. Also have a feeling doing it this way might be bad style, as it looks like a nasty hack
|
|
|
|
|
I think the solution is workable
|
|
|
|
|
johnyy wrote:
It's my understanding that System.Console.Read() reads everything until
It will wait till a key is pressed (not enter key but any key). You can try the method given below by Humpo. Another method might be to subclass the console window.
|
|
|
|
|
Ok... threads I can figure out, Console.Read() I cant. I can't find documentation on this function on msdn, and when i try and use it in my code it wont work because i dont know what it returns (is it a int, if so how do you converty int to char to string?).
Thanks.. ive got a multithread program now
|
|
|
|
|
hope this helps..
class Class1
{
private bool bLoop;
private Thread myThread;
[STAThread]
static void Main(string[] args)
{
Class1 c1 = new Class1();
}
public Class1()
{
bLoop = true;
KeyReader kr = new KeyReader();
kr.KeyEvent += new KeyReader.KeyEvents(KeyEvent);
myThread = new Thread(new ThreadStart(kr.ThreadRun));
myThread.Start();
while(bLoop)
{
System.Console.WriteLine(System.DateTime.Now);
}
myThread.Abort();
}
private void KeyEvent(int k)
{
System.Console.WriteLine("Key Event");
if(k=='e'|| k=='E')
bLoop = false;
}
}
public class KeyReader
{
public delegate void KeyEvents(int c);
public event KeyEvents KeyEvent;
public void ThreadRun( )
{
bool loop = true;
while(loop)
{
int ch = System.Console.Read();
if(KeyEvent != null)
{
System.Console.ReadLine();
KeyEvent(ch);
}
}
}
}
if anyone spots errors in code, please point them out for me
|
|
|
|
|
Hello everyone, is it possible to use the "\" charactor in a string? I need to do this becuase I need to store a folder path (I.E. c:\sierra5\logs\) into a string. Thanks...
|
|
|
|
|
Yes, use \\ or put an @ before the start of the string (@"c:\sierra5\logs\" ).
James
|
|
|
|
|
|
I know JTJ has already answered your question, but just in case you are interested Dr. GUI.NET has written a very good article on the string objects on MSDN. Here is the link.
Strings in the .NET Framework
Nick Parker
|
|
|
|
|
I want to create a Hashtable of strings and function pointers. How can I do that in C#/ASP.NET?
I'm just guessing here...
public string MyFunc(string instr)
{
return instr + "blah";
}
Hashtable table = new Hashtable;
table.Add("myfunc", MyFunc);
string str = "blah";
string blahblah = (table["myfunc"])(str);
something like that? But I'm not sure how to store the function in the hashtable and how to retrieve it and use it.
Todd Smith
|
|
|
|
|
In C# a function pointer is a delegate, so you'll be storing a delegate in the hashtable, and using the string as the key.
The delegate that can be used for MyFunc above would be:
public delegate string FunctionDelegate(string instr);
To add that to the hashtable you would do something like this.
Hashtable table = new Hashtable();
table["myfunc"] = new FunctionDelegate(MyFunc); (you could also use the Add method, but I prefer the array-like access).
Now to get it back out and use it;
FunctionDelegate d = table["myfunc"] as FunctionDelegate;
d(str); I found understanding delegates the hardest part for me to learn; once you get it though you'll wonder why you didn't get it sooner
Good luck,
James
|
|
|
|
|
Sweet. Now I'll be able to pull specific fields out of an ASP.NET form and convert the values before they get updated into the database.
public delegate string HoursToSecsCallbackType(string hours);
HoursToSecsCallbackType fp = new HoursToSecsCallbackType(Utils.HoursToSecs);
Hashtable table = new Hashtable();
table.Add("hours", fp);
string column = "hours";
TextBox textbox = (TextBox)objArgs.Item.FindControl(column);
if (table.ContainsKey(column))
{
HoursToSecsCallbackType fp = (HoursToSecsCallbackType) table[column];
textbox.Text = fp(textbox.Text);
}
Todd Smith
|
|
|
|