|
That's a good idea. I'll give that a try. I can absolutely change my interface. That's why I'm showing the progressBar value in the interface now. I'm not absolutely sure how to send a value when I fire an event, but I'll take a look. Thanks!
|
|
|
|
|
MichCl wrote: I'm not absolutely sure how to send a value when I fire an event
Create your own event and with that, you create your own event arguments class to carry the data you want to send in the event.
|
|
|
|
|
This sample might help you to get going with event usage
public delegate void ProgressChangeHandler(int progress);
class MyClass
{
public event ProgressChangeHandler ProgressChanged;
public void Process()
{
RaiseProgressChange(progress);
}
private void RaiseProgressChange(int progress)
{
if(ProgressChanged!= null)
{
ProgressChanged(progress);
}
}
}
Jibesh V P
|
|
|
|
|
I'm still not sure about the event with parameters!! If I had the delegate above, how would that be used to fire an event and notify the method waiting for the integer value? I started with this, but I'm not sure how to have an event call it. I was looking at this link: http://stackoverflow.com/questions/1488099/call-an-eventhandler-with-arguments[^]
private void _updateProgressBar(object sender, EventArgs e, int i)
{
//call code from here waiting for int i
}
|
|
|
|
|
The delegate you are mentioned here is one that comes with the .Net framework i.e "EventHandler" it was defined like
public delegate void EventHandler(object sender, EventArgs e); inside one of the Framework class. likewise we can also define our own delegates that suits to our need. here instead of using the native handler I defined a custom delegate to fire an event. Read the following articles which explains more about events and delegates. Events-and-Delegates-Simplified and Step-by-Step-Event-handling-in-C#
Jibesh V P
|
|
|
|
|
Ok I will try to explain with your class name
define a event in your interface iCR.cs
public delegate void ProgressChangeHandler(int progress);
interface CRInterface
{
event ProgressChangeHandler ProgressChanged;
int ProcessTWriting(ref byte[] WDat, ref int pb_value)
}
Implement this interface in CRD.cs class
class MyCR: CRInterface
{
public event ProgressChangeHandler ProgressChanged;
public int ProcessTWriting(ref byte[] WDat, ref int pb_value)
{
status = AttemptWrites(ref pb_value);
}
private int AttemptWrites(ref int pb_value)
{
for (int i = 0; i < ((wDat.Length) / 4); i++)
{
RaiseProgressChange(i);
}
}
private void RaiseProgressChange(int progress)
{
if(ProgressChanged!= null)
{
ProgressChanged(progress);
}
}
}
Finally Subscribe for event change in your FormClass i.e PC.cs
private FormLoad(...)
{
cr.ProgressChanged += new ProgressChangeHandler(CR_ProgressChanged);
}
private void CR_ProgressChanged(int progress)
{
progressBar.Value = progress;
}
Hope this helps.
Jibesh V P
|
|
|
|
|
Thanks for the extra info, Jibesh. It's not often I have to deal with events. When I tried to do the above in my CR5.cs (implements iCR),
public event ProgressChangeHandler ProgressChanged;
it says "The type or namespace name 'ProgressChangeHandler' could not be found (are you missing a using directive or an assembly reference?)"
and also, iCR
public delegate void ProgressChangeHandler(int progress);
I get "'ProgressChangeHandler': interfaces cannot declare types"
Maybe it's not going to work with an interface between PC.cs and CR5.cs (implements iCR)?
|
|
|
|
|
The above code sample is working version if you closely look at the sample you can find that delegate method is defined in the dll where iCR is located and you don't need to use the Public access specifier for Interface methods and data.
This will definitely work and I have done same stuff in the past.
ProgressChangeHandler must be defined globally so that this delegate is accessible by all members.
Jibesh V P
|
|
|
|
|
Thank you very much!!!! This is very helpful. I got it building now.
|
|
|
|
|
Good Happy to hear that.
Jibesh V P
|
|
|
|
|
If I could add one more little question onto the above, which I got to work. I also have a C_Comm.cs class which is referenced in my CR5.cs, the original PC.cs, and iCR.cs. It turns out that one area I need to update my progress bar (in PC.cs) from is C_Comm, which is also in a different VS project. I'm trying to get it working, and am getting an error: Cannot implicitly convert type 'ProgressChangeHandler' to C_Comm.ProgressChangeHandler'
Right now it looks like this:
PC.cs (the form code)
public event ProgressChangeHandler ProgressChanged;
public void GetPC(...)
{
cr.ProgressChanged += new ProgressChangeHandler(updateProgressBar);
cb.ProgressChanged += new ProgressChangeHandler(updateProgressBar);
}
public int updateProgressBar(int i)
{
pb.Value = i;
}
iCR.cs (interface)
public delegate void ProgressChangeHandler(int progress);
public interface iCR
{
event ProgressChangeHandler ProgressChanged;
}
CR5.cs (implements iCR)
public event ProgressChangeHandler ProgressChanged;
private int AttemptWrites()
{
for(i=0...)
{
RaiseProgressChange(i);
}
}
private void RaiseProgressChange(int progress)
{
if (ProgressChanged != null)
{
ProgressChanged(progress);
}
}
C_Comm.cs
public delegate void ProgressChangeHandler(int progress);
public class C_Comm{
public event ProgressChangeHandler ProgressChanged;
public int Read(byte[] data, int ind)
{
for(int i...)
{
RaiseProgressChange(i);
}
}
private void RaiseProgressChange(int progress)
{
if (ProgressChanged != null)
{
ProgressChanged(progress);
}
}
}
Do you know how I could get the ProgressBar in PC.cs to be updated also from C_Comm.cs?
|
|
|
|
|
if C_Comm.cs file is common to both project you can remove the delegate declaration inside the interface class and use the delegate inside C_Comm.cs in all places that should be fine
Jibesh V P
|
|
|
|
|
I tried to just have the delegate in my C_Comm.cs (not in iCR), and now in my CR5.cs class, I get the error "The name 'ProgressChanged' does not exist in the current context" in my RaiseProgressChange method. Then if I try to use cb.ProgressChanged != null, I get the error "The event 'C_Comm.ProgressChanged' can only appear on the left hand side of += or -=". I'm not very clear on using events! Do you have any ideas?
|
|
|
|
|
I dont see any error in your previous code other than two declaration of the delegates ProgressChangeHandler.
is C_Comm.cs is defined in a common dll? can you give some more input about the project files where these .cs files are added.
If it was me, I keep all the common implementations/interfaces in a shared dll and refer these dll in different projects rather keeping same .cs files each project.
what are you trying to do here with this 'cb.ProgressChanged != null' checking for null right??
Jibesh V P
|
|
|
|
|
C_Comm.cs is a separate VS project, separate dll, commonly referenced by everything (CR5.cs, PC.cs). Do you think I still need everything except the delegate part in my iCR? The CR5 implements iCR and that's the only way I can see getting the ProgressChanged defined in CR5 from PC.cs, but when I take out the delegate part, I get "The type or namespace name 'ProgressChangeHandler' could not be found (are you missing a using directive or an assembly reference?)". I can't keep my iCR.cs and C_Comm.cs in the same dll because of the whole layout. The VS project layout is:
Project 1 has iCR.cs
Project 2 has PC.cs and a couple of other things. (update - this has form with progress bar)
Project 3 has CR5 (implements iCR) and a couple of other things.
Project 4 has CR_Factory which will return a CR5 through the iCR interface to my PC.cs
Project 5 has C_Comm.cs. It is referenced in PC.cs, CR5, and iCR.
In the future I'll have a CR6 project like the CR5.
As far as cb.ProgressChanged != null, I'm just trying to get what you suggested originally to work with my delegate in my C_Comm. Yes, checking for null before I send the update.
modified 17-Jan-13 16:18pm.
|
|
|
|
|
I dont see any problems here. did you refer Project5 in iCRS
Jibesh V P
|
|
|
|
|
I can't reference CR5 in iCR because that would be an incorrect implementation for factory design pattern. Plus, CR5 is an iCR and if iCR referenced CR5, it would be circular.
|
|
|
|
|
I wound up leaving the original delegate in my iCR and everything you originally recommended above. Then I created a separate delegate and handler in my C_Comm.cs class. I couldn't see any other way to update my progressBar and also share the same delegate and event. Thanks for the help!
|
|
|
|
|
I dont see any error in your declaration, i.e the delegate method is declared in Comm.cs file which is referred in all the other 3(or more project) iCR,CR5 and form Class. so the delegate should be available in all other classes and you need to include the proper namespaces in other project files.
Jibesh V P
|
|
|
|
|
Thank you so much for the help. We have a very small work group here, and they are not programmers and don't understand this stuff (not to mention me having a tough time with events and this architecture). It turned out I wasn't "using" C_Comm in my interface. Once I did that and fixed a couple of declarations to use the C_Comm version of the Handler, all worked.
|
|
|
|
|
Glad to hear this. Good Luck
Jibesh
Jibesh V P
|
|
|
|
|
Thank you! And thanks for sticking with this thread.
|
|
|
|
|
You are welcome!! Cheers!
Jibesh V P
|
|
|
|
|
@jibesh - I added an interface (see my recent question), and my event is null when I try to update my progress bar. I know you have a good idea about events and interfaces. If you could take a look at my newly posted question(Thursday post maybe), I'd appreciate it. Thanks!
|
|
|
|
|
I need to include a pdf file in my sandcastle documentation. The user should be able to navigate to the pdf on clicking it in the .chm file. Is it possible to do this? I've been searching all forums with no proper answer. I have tried using href tag in the xml comment and providing the url of the pdf file. But it opens the browser instead of the pdf file. Has anyone done this before?
-nite_hawk
-- modified 18-Oct-22 21:01pm.
|
|
|
|