|
Martin#, I'm going to push my luck and ask a related question. I'm sure that the answer also lies in reflection somewhere but seeing as it's all new to me and will involve some study I thought I'd see if you could help me.
Would there be a way perhaps of instantiating a new object based on a type that is also obtained during runtime? In other words, I read a file which contains XML (or whatever text based representation of objects) which I then would like to put onto a form.
Let's assume the file holds something like:
Type=Button
Name=MyNewButton
Text=My New Button
Now I can read these into variables, let's call them newType, newName and newText.
How do I instantiate a new object? Again Button newButton = new Button() is easy enough but at runtime it could be Label , TextBox or anything else.
After this is over I promise to make an effort of getting on top of reflection.;)
Thanks,
D
|
|
|
|
|
HEllo,
Also here "System.Reflection" helps you.
string knownAssemblyName = ???;
Assembly asm = Assembly.LoadWithPartialName(knownAssemblyName);
Assembly asm = Assembly.GetExecutingAssembly();
string typeStringOfControl = ???
Type ctrltype = asm.GetType(typeStringOfControl);
ConstructorInfo ci = ctrltype.GetConstructor(Type.EmptyTypes);
object ctrlInstance = ci.Invoke(new object[0]);
All the best,
Martin
|
|
|
|
|
Hi Martin,
Thanks, I really apreciate your help. This method seems to work well, for the most part...
The one problem I have is that ctrlInstance is still of type object even though the Button constructor (or whichever type) is used to instantiate it.
The result is that I can't access any properties that are particular to a specific type directly. For a Button I would like to add an event handler for instance but
ctrlInstance.Click += new System.EventHandler(this.ElementHandler);
wouldn't compile because 'object' does not contain a definition for 'Click'
I was hoping that I could then rather to the following:
PropertyInfo actPI = myControl.GetType().GetProperty("Click");
if (actPI != null)
actPI.SetValue(myControl, new System.EventHandler(this.ElementHandler), new object[0]);
Although this compiles (obviously), it doesn't work because actPI is null .
I hope I'm not getting too tedious with my questions but I appreciate your help.
Dewald
|
|
|
|
|
Hello Again,
Dewald wrote: I hope I'm not getting too tedious with my questions but I appreciate your help.
No way!
This is a very interesting discusion, thanks for that!
Now to your problem:
Reflection in combination with delegates is something I have never done.
So I can only give you a maybe dirty solution (but maybe also the only one possible).
I would cast to the object to the appropriate type and then do your stuff.
...
Button actButton = ctrlInstance as Button;
if(actButton!=null)
{
actButton.Click+=...
}
If you have more than one type to validate for some other action with Label, CheckBox, ...
if(ctrlInstance is Button)
{
Button actButton = ctrlInstance as Button;
actButton.Click+=...
}
else if(ctrlInstance is Label)
{
Label actLabel = ctrlInstance as Label;
}
...
Hope that someone will come up with a cleaner solution,
but maybe it fitts your needs.
All the best,
Martin
|
|
|
|
|
Martin,
I thought of following that approach so if you don't have a more elegant sollution then I suppose I'll just use it. It works fine though but, as you said, it's just not as pretty.
If I may, I'd like to return to the original question quickly. You showed me how to use reflection to instantiate an object of any type and then with the SetValue method of PropertyInfo I can set the value of a property programatically.
I just discovered that, while it works perfectly for properties that have string values, it won't work for property that have a value of some funny type. Take Button.Size for instance, if I have
PropertyInfo actPI = myControl.GetType().GetProperty(myPropertyName);
if (actPI != null)
actPI.SetValue(myControl, myPropertyValue, new object[0]);
with myPropertyName = "Size" and myPropertyValue = "75,24" then obviously I'm going to get into trouble.
I could've used actPI.SetValue(myControl, new Size(100, 24), new object[0]); but I will only know at runtime that the property I'm trying to change is Size and I have to store the value in a file (or DB) in some string representation.
Is there an easy workaround for this?
Cheers,
Dewald
|
|
|
|
|
Hello,
Now it looks like you really should look into "Serialization".
In combination with XML it is well supported in .NET, and there are tonns of articels about that.
Like:
this CP article[^]
or look at google![^]
Hope it helps you!
All the best,
Martin
|
|
|
|
|
Hi Martin,
Yes, I think you're correct. I think I will take it upon me to study Reflection and Serialization this weekend.
Thanks again you've been of fantastic help.
Cheers,
Dewald
|
|
|
|
|
You are allways wellcome!
All the best,
Martin
|
|
|
|
|
Hi
I m getting a problem while executing my program. Actually I m trying to send video file from server to client using BufferedStream with TCP. When I debug it,program runs fine and exact video is recieved on the client side. But when I run prog. normally(without Debugging),I get Corrupted video.I m not getting a clue on how this file corrupts when I run normally as this doesn't happen While I debug.
PLZZZZZZZZZ TELL ME ASAP WHAT IS THIS ERROR AND HOW TO RESOLVE IT.
Regards,
Shanzay
|
|
|
|
|
Hi,
Read the file till end into the buffer, and then try sending it.
Regards,
Adeel
Do rate the reply, if it helps or even if it doesnot, because it helps the members to know, what solved the issue. Thanks.
|
|
|
|
|
I m sending through streaming by using 16KB buffer as:
byte buf = new byte[16384];<br />
FileStream inStream = File.OpenRead(dlgOpen.FileName); BufferedStream bufInStream = new BufferedStream(inStream);<br />
int bytesRead;<br />
<br />
while ((bytesRead = bufInStream.Read( buf, 0, 16384)) > 0)<br />
sock.Send(buf,buf.Length,SocketFlags.None); <br />
/////////////////////////////////////
At Recieving Side
<br />
FileStream outStream;<br />
outStream=File.OpenWrite(filepath);<br />
rcvfilebuf=new byte[16384];<br />
while(true)<br />
{<br />
socket.Receive(rcvfilebuf);<br />
<br />
bufOutStream = new BufferedStream(outStream);<br />
bufOutStream.Write(rcvfilebuf, 0, rcvfilebuf.Length);<br />
}<br />
This code is doing well while debugging but not in normal running of application.
Shanzay
|
|
|
|
|
Hi,
Tried without reading in buffers?
Reading the whole file in one I/O operation, and then sending it might solve the issue.
Regards,
Adeel
Do rate the reply, if it helps or even if it doesnot, because it helps the members to know, what solved the issue. Thanks.
|
|
|
|
|
The problem is at the receiving end, your file is too large.
What will the value be of rcvfilebuf.Length?
Doesn't Socket.Receive return something?
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- use PRE tags to preserve formatting when showing multi-line code snippets
- before you ask a question here, search CodeProject, then Google
|
|
|
|
|
Yah it returns and its size is 16KB.And I've solved this problem by using thread.sleep(30) before send() from server side but now the file which I m getting at client side the frames of that video file are overlapping so what to do in this case as if File size 10MB then it gives required output but if larger than 20MB then frames becomes overlap in video.
So PLZ SUGGEST NOW How to solve this
Thanx
Shanzay
|
|
|
|
|
DeepOceans wrote: Yah it returns and its size is 16KB
I don't think so.
If the sender's file size is a multiple of 16KB, then all buffers will contain 16KB.
If the sender's file size is not a multiple of 16KB, the last buffer sent will contain
less, but the receiver, the way you did it, will still store 16KB, i.e. the buffer will
contain some older data and write that to the file too. That's what my previous reply
was about.
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
I handle this issue at Server(sending side)but didnt mention before as like this:
<br />
while ((bytesRead = bufInStream.Read( buf, 0, 16384)) > 0)<br />
<br />
if(bytesRead<16384)<br />
sock.Send(buf,bytesRead,SocketFlags.None); <br />
else<br />
sock.Send(buf,buf.Length,SocketFlags.None); <br />
so then by this way client recieves data though in 16KB buffer but I got success in playing 10MB file at client side.but now file size of more than 15MB is not playing properly. In this case frames are overlapping so what is prob. here?
Shanzay
|
|
|
|
|
DeepOceans wrote: while ((bytesRead = bufInStream.Read( buf, 0, 16384)) > 0)
if(bytesRead<16384)
sock.Send(buf,bytesRead,SocketFlags.None);
else
sock.Send(buf,buf.Length,SocketFlags.None);
this is not my point; and it is a useless complication, just write
sock.Send(buf,bytesRead,SocketFlags.None);
You should fix the receiver!
Luc Pattyn [Forum Guidelines] [My Articles]
this months tips:
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use PRE tags to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Hi. I have posted this message a number of times and nobody seems to be able to help me or advise me and I need a bit of guidance. I am sorry for having to call on you direct but I think you may be the only one that will be able to answer me or help me.
Firstly, I would only like to export the records that are marked as N in the Exported Column in my DB. Then, as the record is exported I would like to mark the record as Y to show that it has been exported. This is so that it doesn't get re-exported next time round. How do I do this?
private void toolStripButton2_Click(object sender, EventArgs e)
{
StreamWriter sw = new StreamWriter(@"C:\nefz" + DateTime.Today + ".csv", false);
DataTable dt = m_dtCallCentre;
int iColCount = dt.Columns.Count;
for (int i = 0; i < iColCount; i++)
{
sw.Write(dt.Columns[i]);
if (i < iColCount - 1)
{
sw.Write(";");
}
}
sw.Write(sw.NewLine);
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < iColCount; i++)
{
if (!Convert.IsDBNull(dr[i]))
{
sw.Write(dr[i].ToString());
}
if (i < iColCount - 1)
{
sw.Write(";");
}
}
sw.Write(sw.NewLine);
}
sw.Close();
}
|
|
|
|
|
Gosh - I'm blushing....
If there is more than one user on the DB and so you can't know for sure that all the records in the DB have been read, then collect the Ids of the records you have read as you read them to build an SQL string like update myTable set Exported = 'Y' where ID in .... where .... is your list of Ids.
If this is a single user database then just do an update on all records - update myTable set Exported = 'Y'. And I assume you look for 'N' when you do the read, so you only export new records ?
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Thanks Christian. I have posted the same question a few times and have been advised to go in and do this in the DB whereas I want to do this when I run the export. Why write code if I have to go and do something manually?
I plan on runnign the export after hours when nobody is using the system. So, basicaly what you saying is, After the export just do an update of all records annd set them to Y?
When doing the export, how do I only look for records that have the value N. DO I have to set this in the export routine?
Thanks again.
|
|
|
|
|
Yes, if you're the only one using it, you could even do a proc that says
select * from tbl where exported='N'
update tbl set exported = 'Y'
Although, I reckon it's safer to do the update AFTER you're sure you've got the data and used it
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Kwagga wrote: I think you may be the only one that will be able to answer me or help me.
Christian sure is a smart guy - no doubt about it. However, directing this at him and sticking your head that far up his arse kinda puts other people off of trying to help you.
Ill tell you this much - the right way to do this is to
1) Select only those rows that have Exported = 'N' (As CG said)
2) Export those records received from the query
3) Update only those records exported sucessfully with Exported = 'Y'
If you do step 3) before step 2) You should consider doing this within a transaction so that if any part of the export operation fails (and believe me it will at some point) the unexported records get set back to Exported = 'N'.
|
|
|
|
|
But, even if he does 1 and 3 in a transaction, the transaction will end before he starts 2. That's why I was also advocating the order you're suggesting.
Christian Graus - Microsoft MVP - C++
"also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )
|
|
|
|
|
Totally, Ive done it both ways:
Select/Export/Update (No xact needed)
Xact Begin/Select+Update/Export/Xact commit (xact necessary to maintain integrity)
I think I favour 1, cant remeember why I ever did 2.
|
|
|
|
|
Hello,
I’m developing non commercial software using Visual C#. In the software, by clicking a button I can open under DOS program, which is named “Linear”, using code bellow
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = "start";
proc.StartInfo.Arguments = "Linear";
proc.Start();
proc.WaitForExit();
The Linear lives in the same folder with my software so I don’t use full path for calling Linear.
When I debug my software, the under DOS program could be called and no problem at all. Then, I made setup application of my software, install it in my computer and the software work smoothly.
The problem is when I install my software on other computers and I click the button to open the under DOS program, suddenly warning box occurs with message bellow
///
See the end of this message for details on invoking
just-in-time (JIT) debugging instead of this dialog box.
************** Exception Text **************
System.ComponentModel.Win32Exception: The system cannot find the file specified
at System.Diagnostics.Process.StartWithShellExecuteEx(ProcessStartInfo startInfo)
at System.Diagnostics.Process.Start()
at Fondamen.Run.button3_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
************** Loaded Assemblies **************
mscorlib
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/mscorlib.dll
----------------------------------------
Fondamen
Assembly Version: 1.0.0.0
Win32 Version: 1.0.0.0
CodeBase: file:///C:/Program%20Files/Institute%20Technology%20of%20Bandung/Setup%20Fondamen/Fondamen.exe
----------------------------------------
System.Windows.Forms
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
----------------------------------------
System
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
----------------------------------------
System.Drawing
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
----------------------------------------
System.Configuration
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
----------------------------------------
System.Xml
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.832 (QFE.050727-8300)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
----------------------------------------
Accessibility
Assembly Version: 2.0.0.0
Win32 Version: 2.0.50727.42 (RTM.050727-4200)
CodeBase: file:///C:/WINDOWS/assembly/GAC_MSIL/Accessibility/2.0.0.0__b03f5f7f11d50a3a/Accessibility.dll
----------------------------------------
************** JIT Debugging **************
To enable just-in-time (JIT) debugging, the .config file for this
application or computer (machine.config) must have the
jitDebugging value set in the system.windows.forms section.
The application must also be compiled with debugging
enabled.
For example:
<configuration>
<system.windows.forms jitdebugging="true">
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.
///
I don’t know wheter it is caused by different environment variables or not. Even, if it is caused by different environment variables, I don’t know how to cope this. Please give me solution. Thank you before.
Andhika Sahadewa
|
|
|
|
|