|
Well, maybe. The event is made by the class library when it needs something from the end-user. So the process is:
class library (needs something)
<--accessed through--> program (can ask the user for something)
<-- interfaces with --> user (can supply something)
The question is, how do I handle that "something"? Right now I am making it a return value of the event. The event is part of the class library; the program has an event handler; and the event handler queries the user, and returns whatever the user inputted.
Are you saying that I should put the "return value" in the event args? So that the program's event handler gets the user's input, stuffs it in the event args, and then the class library reads out what the program put into the event args?
-Domenic Denicola- [CPUA 0x1337]
“I was born human. But this was an accident of fate—a condition merely of time and place. I believe it's something we have the power to change…”
|
|
|
|
|
Domenic wrote: Are you saying that I should put the "return value" in the event args? So that the program's event handler gets the user's input, stuffs it in the event args, and then the class library reads out what the program put into the event args?
Yes that it how it is normally done in events. Event should always have this signature: void Foo(object sender, YourEventArgs e); . A sample for your needed feedback ist for example the CancelEventArgs used in the framework. It has a Cancel property which can be set by receivers. If you don't want to stick to this pattern you should use a normal delegate instead.
Robert
|
|
|
|
|
Thank you! The CancelEventArgs example was very helpful; now I can feel that, although it seems natural to use a return value, in reality it's done another way, and I should stick to that.
-Domenic Denicola- [CPUA 0x1337]
“I was born human. But this was an accident of fate—a condition merely of time and place. I believe it's something we have the power to change…”
|
|
|
|
|
If you consider the return value natural, maybe you should consider changing the event to a single "settable" delegate. So instead of hooking up to the event you set a callback delegate. This way you can only have one hooked up - and hence a return value makes sense. I am not saying this is better than having a settable result property in the eventargs - just another way of doing it.
|
|
|
|
|
I'm not really sure how this effects the message pump, but I feel like getting user feedback within an event handler in general is a bad idea because it will (I think) halt message handling while you wait for the input. Why not process this on the actual thread that you are calling it from, with a public method called "GetPin()", which will check to see if the pin is already entered and return that if it exists, or return the new pin provided by the user through some UI.
Jeff
|
|
|
|
|
OK, but where should this method go? The class library is what actually needs to use the PIN; the program should be allowed to choose any mechanism for giving the library a PIN that it wants. Maybe the program generates random PINs ('cuz someone is using the library to be l33t hacker); maybe the program gets it from the user; maybe the program looks it up in a database. The class library doesn't care though, it just needs a PIN---how do I get the PIN from the program to the class library?
-Domenic Denicola- [CPUA 0x1337]
“I was born human. But this was an accident of fate—a condition merely of time and place. I believe it's something we have the power to change…”
|
|
|
|
|
Basically, you would implement an interface called IPinProvider, which the form would extend. Then, instead of having your mainform register to listen to the event from the Dll, have it send a reference to itself to the dll. Then the Dll can call the method directly. This will also increase security because a third-party application could not just register for the event from the Dll, and intercept the return value. If you wanted to, you could even check to make sure that the calling assembly is the Dll that you expect it to be from the MainForm class using the System.Reflection namespace.
public Interface IPinProvider {
int GetPin();
}
public class MainForm : Form, IPinProvider {
DllClass myDll = new DllClass();
...
public MainForm() {
myDll.ParentForm = this;
}
...
private int GetPin() {
...
}
}
public class DllClass {
private IPinProvider myPinProvider = null;
public IPinProvider ParentForm {
set { myPinProvider = value; }
}
private int GetPin() {
return (myPinProvider == null ? int.MinValue : myPinProvider.GetPin());
}
}
Hope this helps!
-Jeff
|
|
|
|
|
Hello all. Is it possible to have the property's getter public whereas the property's setter protected? Don't know, something like:
string Property
{
public get { return _property; }
protected set { _property = value; }
}
If possible, how can I do so?
Thanks in advance.
Hope is the negation of reality - Raistlin Majere
|
|
|
|
|
What happens when you try it?
The following will work nicely:
<code>public string Property
{
get { return _property; }
protected set { _property = value; }
}</code>
The early bird who catches the worm works for someone who comes in late and owns the worm farm. -- Travis McGee
|
|
|
|
|
Oh, I see. My code didn't compile whereas yours actually did. Thanks a lot!
Regards.
Hope is the negation of reality - Raistlin Majere
|
|
|
|
|
No problem
The one thing to remember is that the accessibility of the property must be greater than or equal to the accessibility of the most accessible getter or setter - that's probably the compile error you were getting.
Without an access modifier, properties by default are protected, but you were trying to make the getter public. Since the property itself was protected, a public getter isn't allowed.
The early bird who catches the worm works for someone who comes in late and owns the worm farm. -- Travis McGee
|
|
|
|
|
I had no idea you could do this, but have wanted this feature since I started using C#. Good find!
Jeff
|
|
|
|
|
Thanks
The early bird who catches the worm works for someone who comes in late and owns the worm farm. -- Travis McGee
|
|
|
|
|
This was introduced with .Net 2 and I love it.
Robert
|
|
|
|
|
I am getting an ArgumentNullException when I call ToolStripManager.LoadSettings(this) from a form on load event within the application. My scenario is as follows...
public class Panel1 : UserControl {
// This class contains a ToolStripContainer with a unique name, and some toolstrips
}
public class Form1 : Form {
private ToolStripContainer myToolStripContainer;
public Form1() {
Panel1 myPanel = new Panel1();
ToolStripContainer tsc = null;
// Get the ToolStripContainer from myPanel
foreach (Control c in myPanel.Controls) {
if (c is ToolStripContainer) {
tsc = (ToolStripContainer) c;
break;
}
}
// Sets up the default layout
if (tsc != null) {
/* Take all the ToolStrips from myPanel and add them to
* myToolStripContainer in a single row
*/
}
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
// Get the saved layout if it exists (throws unexpected exception)
ToolStripManager.LoadSettings(this);
}
protected override void OnFormClosing(FormClosingEventArgs e) {
base.OnFormClosing(e);
ToolStripManager.SaveSettings(this);
}
}
Does anyone have any idea as to how I can save and reload these settings? I have copied the exception below. Thanks,
ArgumentNullException
"value cannot be null"
at System.Windows.Forms.ToolStripItemCollection.CheckCanAddOrInsertItem(ToolStripItem value)
at System.Windows.Forms.ToolStripItemCollection.Insert(Int32 index, ToolStripItem value)
at System.Windows.Forms.ToolStripSettingsManager.ApplyToolStripSettings(ToolStrip toolStrip, SettingsStub settings, Dictionary`2 itemLocationHash)
at System.Windows.Forms.ToolStripSettingsManager.ApplySettings(ArrayList toolStripSettingsToApply)
at System.Windows.Forms.ToolStripSettingsManager.Load()
at System.Windows.Forms.ToolStripManager.LoadSettings(Form targetForm, String key)
at System.Windows.Forms.ToolStripManager.LoadSettings(Form targetForm)
at Form1_Load(Object sender, EventArgs e) in ...
Jeff
|
|
|
|
|
Try calling ToolStripManager.LoadSettings in the OnShown method instead. Without starting up Visual Studio and trying it out, I suspect that you are hitting a problem where this hasn't been initialised fully because of the sequence of events when loading the form.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Nope, still getting the same exception.
Jeff
|
|
|
|
|
In the app I'm writing I would like to be able to check if any concurrency violations have occurred on the database it's monitoring in the recent past.
In SQL Server Management studio I can run the command
DBCC CONCURRENCYVIOLATION
which gives me the message back (where I forced concurrency violations):
Concurrency violations since 2007-10-10 10:47:47.383<br />
1 2 3 4 5 6 7 8 9 10-100 >100<br />
4727 2800 1118 0 0 0 0 0 0 0 0<br />
Concurrency violations will be written to the SQL Server error log.<br />
DBCC execution completed. If DBCC printed error messages, contact your system administrator.
So this is the info I need, the way that I'm trying to get it into my program is:
conn.Open();<br />
<br />
conn.InfoMessage += new SqlInfoMessageEventHandler(SqlMessageEventHandler);<br />
<br />
SqlCommand c = new SqlCommand("DBCC CONCURRENCYVIOLATION", conn);<br />
c.ExecuteNonQuery();
where conn is my SQL connection and SqlMessageEventHandler grabs the error message:
public void SqlMessageEventHandler(object sender, SqlInfoMessageEventArgs e)<br />
{<br />
string CVTest = "";<br />
foreach (SqlError err in e.Errors)<br />
{<br />
CVTest += err.Message;<br />
} <br />
<br />
}
The problem is that the "CVTest" sting I'm using to monitor the message only gives me back
DBCC execution completed. If DBCC printed error messages, contact your system administrator. rather than the whole message as in Server Management Studio. This occurs whether the DB I'm checking has violations logged or not.
Does anyone know how I can get all the information that DBCC CONCURRENCYVIOLATION should return?
Alternatively, if anyone knows a better way to programatically check for concurrency violations that have occurred on the database that would be great, since parsing that message to determine can't be the most efficient way.
Thank you.
|
|
|
|
|
I might be wrong but have you looked at what is inside the Message property of the SqlInfoMessageEventArgs in your case:
public void SqlMessageEventHandler(object sender, SqlInfoMessageEventArgs e)
{
string CVTest = e.Message;
foreach (SqlError err in e.Errors)
CVTest += Environment.NewLine + err.Message;
}
Robert
|
|
|
|
|
Hey, thanks for the reply. Yeah, the Message property only contains that one line response as well instead of the whole message.
Anyone have any other ideas on how to check for concurrency violations?
Thanks
|
|
|
|
|
Hi all,
I'm having some trouble getting with this:
char temp = System.Console.ReadKey();
//Throws an exception
So I tried System.Console.ReadKey().KeyChar which returns the ascii value of the key I entered...
Basically I need to get a key that falls in the range of 0-10
There's a validation line that handles if temp > 0 || temp < 10... but I can't get the character to convert into an int properly.
Thanks
Humble
|
|
|
|
|
if (Char.IsNumeric(Readkey().KeyChar)) should tell you if it's a number of not.
Deja View - the feeling that you've seen this post before.
|
|
|
|
|
Yeah, I've got the validation portion down...
I need to get the character, which if entered proprly is an integer number, and convert it into an integer for processing.
|
|
|
|
|
Probably an easier way but this seems to work:
int val = Convert.ToInt32(e.KeyChar.ToString());
Good Luck!
“You can't teach people to be lazy - either they have it, or they don't.”
-Dagwood Bumbstead
|
|
|
|
|
Hi all!
I must set a psw to a directory, any ideas??
thanks
Bye
|
|
|
|