|
There are two ways to do this, either by public/internal properties in Form2 or passing an instance of a custom class derived from EventArgs . Either will require some kind of signalling to Form1 that the data is ready.
As previously mentioned, if Form1 shows Form2 via ShowDialog() then you can expose a property in Form2, set the DialogResult of Form2 to DialogResult.OK and check for that as a result of the ShowDialog() call, accessing the property.
This same procedure can also be done by subscribing to Form2 s FormClosing event, although the dialog result is a better alternative as you have information relating to the success/failure of user interaction.
Alternatively, Form2 can raise a custom event subscribed to by Form1 . If using this method (the one I prefer) then you can pass a custom event args class instance along with the event that contains only the relevant data - nice and clean and no need to expose properties in Form2 to the whole world.
|
|
|
|
|
Yes , He can write a custom event.
|
|
|
|
|
This type of question: communication of data or events between two forms, is among the most commonly asked and answered type of question on QA in CP.
The critical piece of information to have, imho, in considering a solution is to know under what circumstances Form1 and Form2 (to use your form names) are created:
1. Keeping a run-time created reference: if Form1 creates Form2, or Form2 creates Form1: at the moment of creating it: the Form that creates has a reference to the other Form it has created.
That reference can be stored, and, then, all public properties (and methods, or anything else that's public) can be accessed by the creating Form.
In terms of the question of knowing when Form2 is closed: if Form1 creates Form2: at the moment its created and assigned to some variable in Form1: you can immediately subscribe to Form2's Closing or Closed events, and add an EventHandler defined in Form1.
Here's a code example that demonstrates both the above. First, this is implemented in Form2:
public DataGridView Form2DataGridView { get; set; }
private void Form2_Load(object sender, EventArgs e)
{
Form2DataGridView = dataGridView1;
} And, then, this is implemented in Form1:
private Form2 NewForm2
private void Form1_Load(object sender, EventArgs e)
{
NewForm2 = new Form2();
NewForm2.Closed += new EventHandler(NewForm2_Closed);
NewForm2.Form2DataGridView.SelectionChanged += new EventHandler(Form2DataGridView_SelectionChanged);
}
private void NewForm2_Closed(object sender, EventArgs e)
{
}
public void Form2DataGridView_SelectionChanged(object sender, EventArgs e)
{
} 1.a. The special case of using 'ShowDialog' for presentation of a Form is a special case of this: imho, nothing in the OP suggests 'ShowDialog' is being used. But, you have some good answers here, now, based on the assumption you use 'ShowDialog.' But, please note that you can create one, or both Forms, once, and keep a reference ... if one Form creates the other ... just as described above. Just re-use the reference to the instance of the Form in the ShowDialog mode.
1.b. The special case where both instances of Form1 and Form2 are created by some other entity: well, you can adapt what's suggested in points #1~2. ... edit ... This also is the case, imho, where you may explore the use of Interfaces to pass instances of Forms that implement the Interface cast to the Interface so you effectively limit what is exposed by the passed object. S. A. Kryukov often advocates this method in his QA answers: for example:[^]. ... edit ...
2. Injection: This usually means that one Form has a "vacant" public property, and another Form, when creating the second form with the property sets the value of the public property.
So, Form1 could have a public property of type DataGridView, and in Form2's Load event, Form2 could set the value of that property to the instance's DataGridView: but look at what is implied by that: Form2 must have access to the instance of Form1 ! To me this is "dog wag tail" implemenation: where this makes sense is if Form1 contains the DataGridView, and Form1 creates Form2, and Form2 needs access to the DataGridView on Form1. Then, this is easy because Form1 has access to the instance of Form2 at the moment it creates it.
2.a. I have to admit I have a strong bias against the idea of injecting a reference to a whole Class, or Form, into another Form or Class because I believe this is a violation of the principle of "separation of concerns."
Does Form1 really need access to everything public in Form2 ? If the answer is "yes," then I'd go for code as shown in the example above. But, if the answer is "no," then I'd modify Form1 code as shown above:
private DataGridView F2DataGridView;
private void Form1_Load(object sender, EventArgs e)
{
Form2 NewForm2 = new Form2();
NewForm2.Closed += new EventHandler(NewForm2_Closed);
F2DataGridView = NewForm2.Form2DataGridView;
F2DataGridView .SelectionChanged += new EventHandler(F2DataGridView _SelectionChanged);
}
private void NewForm2_Closed(object sender, EventArgs e)
{
}
public void F2DataGridView _SelectionChanged(object sender, EventArgs e)
{
} The difference in code may seem trivial: but, this implementation means that the only "exposed" object in Form2's instance within Form1's instance is the DataGridView on Form2, because the variable NewForm2 exists only in the scope of Form1's Load EventHandler.
2. Use of some "external" class to expose objects to other classes: You can create a public static class that maintains public Properties which can be set in each Form's 'Load, or 'Shown, EventHandlers, and then are visible to any Form in the same NameSpace. You could even set EventHandlers within that static class.
3. Raising events: This is probably the strategy most appropriate for the scenario you have described, particularly since it enables multiple subscribers to consumers (creators and users) of the instance(s) of Form2.
I've omitted code examples for #2~3, believing they are easy to find here on CP, within articles, tip/tricks, and QA, but if you have further questions, just ask.
"For no man lives in the external truth among salts and acids, but in the warm, phantasmagoric chamber of his brain, with the painted windows and the storied wall." Robert Louis Stevenson
modified 14-Dec-11 6:42am.
|
|
|
|
|
For any sort of complex application, both forms should be looking at some non-UI data model. So all Form2 should have to 'pass back' to Form1 is a selected index or an identifier for the model object that corresponds to the selected row.
Without knowing what the UI context of these two forms is (does Form2 spawn Form1 as an editor? are both forms top level forms? etc) it's hard to be more detailed than that. But the key point is that the data grid on Form2 should be a view on an IList<YourDataModelClass> (well, possibly, a BindingList or a BindingSource on a List) and the various controls on Form1 should be a view on the properties of a YourDataModelClass. You can achieve this with data binding or manually setting properties, and you'll probably want either the model class or a view-model to implement change notification (INotifyPropertyChanged) so that when you update things from Form1, Form2 also refreshes its view. If you're using WPF then you can just use Binding attributes in the XAML.
As Bill says this is a pretty common question in Q&A so you might want to search there and have a look at some of the recommended answers.
|
|
|
|
|
the relevant code
public static explicit operator ExcelWorksheet(Worksheet worksheet)
{
return new ExcelWorksheet(worksheet, 1,1);
}
public static explicit operator Worksheet(ExcelWorksheet worksheet)
{
return worksheet._worksheet;
}
...I'm trying to introduce a cast from the Interop.Excel.Worksheet to our Biz.Custom.ExcelWorksheet so that I can prep the COM proxy outside of the existing process, and allow an explicit cast from a valid COM Worksheet to be accepted as the custom's structurally subtyped property.
I researched the error and found out that this did not make the prioritization list to be removed from C#4 but could not find a workaround.
Does anyone have the proper incantation that will allow me to cast from the COM object to my custom?
Being required to convert these to "FromWorksheet" and "ToWorksheet" methods seems *completely* asinine.
"I need build Skynet. Plz send code"
modified 13-Dec-11 10:57am.
|
|
|
|
|
This is by design, as shown by this quote from the C# spec: "User-defined conversions are not allowed to convert from or to interface-types. In particular, this restriction ensures that no user-defined transformations occur when converting to an interface-type, and that a conversion to an interface-type succeeds only if the object being converted actually implements the specified interface-type". (source[^]). I don't really understand why you can't cast from an interface, but there you have it.
Having something that looks like a cast that actually switches to a completely different COM service is probably a bad thing anyway, though. When the conversion is so simple I recommend you just use 'new ExcelWorksheet(...)' and 'worksheet._worksheet' inline (well okay that last one should probably use a read property not the field directly).
|
|
|
|
|
Hello,
I am writing a project which sends SQL query to server, it runs it and returns back to client the results using streaming.
The flow is sending query,clientIP and port the client is going to listen to using WCF. before sending the WCF, the client opens a listener on the chosen port, and waits for a networkStream from the server. this done in a seperate thread. meanwhile the client sends the WCF request (with query,client ip, client port) to server and it returns the results to the waiting client on the right port.
All this done in seperate thread so i can run several queries simultanesly from the same client. After i received the results i am trying to close the TcpListener and TcpClient opened in the client side (in the opened thread). But when the other thread running it throws exception: Unable to read data from the transport connection: A blocking operation was interrupted by a call to WSACancelBlockingCal.
If i don't close the listener and client it works fine.
So how can i close the TcpListener and TcpClient in the thread without causing problem to the second thread .
TcpListener and TcpClient are not static.
Code:
private void OpenListenerTask(int port,AutoResetEvent resetEvent)
{
try
{
NetworkStream getStream = StartListenerGetStream(port, resetEvent);
string localIp = Dns.GetHostAddresses(Dns.GetHostName())[0].ToString();
var networkReader = new Reader(getStream, localIp, _sendPort.Value, _query);
networkReader.Start();
}
catch (Exception e)
{
Console.WriteLine(e.GetBaseException().Message);
}
//close TcpClient & TcpListener after data/error received
_client.Close();
_listener.Stop();
}
private TcpClient _client;
private TcpListener _listener;
private NetworkStream StartListenerGetStream(int port,EventWaitHandle resetEvent)
{
var tcpListener = new TcpListener(port);
tcpListener.Start();
_listener = tcpListener;
//tcpListener.Server.Blocking = false;
resetEvent.Set();
var tcpClient = tcpListener.AcceptTcpClient();
_client = tcpClient;
return tcpClient.GetStream();
}
|
|
|
|
|
michaelgr1 wrote: i am trying to close the TcpListener and TcpClient opened in the client side
You can't close a TcpListener in the client. The client doesn't own nor have access to that.
|
|
|
|
|
yes,
but in my solution, probably i didn't explain it. The server sending the data and the client receives it. So the listener is opened in the client side
|
|
|
|
|
I take it that your listener has nothing to do with the terminology in socket communication?
Why not use sender and receiver? That takes away the uncertainty of what issue you are really facing.
Cheers, AT
Cogito ergo sum
|
|
|
|
|
The "server" is the one that opens the listener.
The "client" is the one that connects with a client socket to the server (where the listener is.)
I don't care how you label your app(s).
And what I said holds. The client can't close the listener.
The client can close the client socket.
The server can close the client socket (the one it created based on a listener request.)
|
|
|
|
|
This is my first post to discussion so please forgive any mistakes of protocol etc
I am looking to write a 6502 (and possibly later z80) cross assembler to run on the pc using c#. My question is not for code but rather for technique and approach. As I have not done this sort of project before I was wandering what techniques I should use to interpret a line of code. Bearing in mind I need to identify both the instruction and addressing mode.
I can of course actually do this already by either using regular expressions or simply string manipulation but I'd like to know how it's should be done. Other people must have spent years writing assemblers and languages and must know the best approach.
Hope that all makes sense. Discuss .............
Derek
|
|
|
|
|
Let me first admit I'm not a big fan of Regex as they can be powerful, but also cryptic and slow. I do use them in some cases, e.g. I used a few for some of the web page parsing inside CP Vanity (see one of my articles).
I would not even consider using them while writing a compiler or cross-assembler (which I have done dozens of time, mostly in Fortran and later in C). BTW: the really fun part is writing a simulator to go with it.
I'd suggest you write methods (based on string manipulations) that check for and extract a label, a directive or instruction, a first operand, a second operand, etc.
FWIW: everything that can be done with Regex, can also be done without them. I see them as a language add-on, just like LINQ. You can use it if you want, you don't have to.
|
|
|
|
|
Thanks Luc, nice to have the view of someone who has actually done it.
Thanks
|
|
|
|
|
I know one z80 assembler that is written using only string manipulation (not even regex).. it's a nice assembler to use, but the source is a bit of a mess.
Anyway, as usual when parsing some non-trivial, I would suggest using an actual parser. Depending on whether/which parser generator you use, things like "include" may be a little hacky.
But of course string manipulation works fine too.
|
|
|
|
|
I have used Antlr[^] for a not dissimilar task in the past.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Thats not something i'd thought about, thats for this.
Derek
|
|
|
|
|
Derek Henderson wrote: how it's should be done
Write a parser.
Don't use a tool since it appears you haven't done this before. The project is simple enough that it can be used as a learning experience for the basics.
Derek Henderson wrote: Other people must have spent years writing assemblers and languages and must
know the best approach.
Buy the Dragon book. That isn't the name but you can find it by looking for that (add 'compiler')
|
|
|
|
|
Im problem is like this.
Im getting these exceptions when running my application.
"A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The specified network name is no longer available.)"
after this exception
"An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)"
In mssql server machine SQl server browser is also enabled and firewall is also disabled.
Please help.
|
|
|
|
|
Don't post your question on multiple locations. Already I have answered here[^]
Always give us some time for the answers.
|
|
|
|
|
Hi.
There is my problem.
I've created a wpf 4.0 app. When I debug and run it from vs 2010, there is no problem.
At the same pc, when I try to run the .exe, the application crashes.
The error is the following
EventType : clr20r3 P1 : application.exe P2 : 1.0.0.0 P3 : 4ee325f2 P4 : mscorlib P5 : 4.0.0.0 P6 : 4e181ae3 P7 : 41ed P8 : 460
P9 : system.windows.markup.xamlparse
Why is this happening? Any ideas?
|
|
|
|
|
Over 43000 results for the google search phrase "wpf clr20r3" [^]
".45 ACP - because shooting twice is just silly" - JSOP, 2010 ----- You can never have too much ammo - unless you're swimming, or on fire. - JSOP, 2010 ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass." - Dale Earnhardt, 1997
|
|
|
|
|
Hi,
I am using OpenXML to open an existing Word document and modify it. After modifications I want to save it to a database. When I am using a stream in the WordprocessingDocument.MainDocumentPart.Document.Save method, only the main document part is saved and not the whole docx file.
Is there a method available which saves the whole file to a stream or converts it to a byte array?
Thx,
Danny
|
|
|
|
|
if you want to store an existing file in a database, you don't care about the file content, it is just bytes to you.
This implies you don't want to know what application did create the file, and hence you don't involve Word in doing the job. Use Word to create, alter, and save the document to disk; then use file operations and database operations to store it all in a BLOB, as if it were an image or anything else that fits in a byte array.
|
|
|
|
|
dennieku wrote: When I am using a stream in the WordprocessingDocument.MainDocumentPart.Document.Save method, only the main document part is saved and not the whole docx file.
That's because the <a href="http://msdn.microsoft.com/en-us/library/cc840441.aspx">MainDocumentPart</a>[<a href="http://msdn.microsoft.com/en-us/library/cc840441.aspx" target="_blank" title="New Window">^</a>] is merely a part of the document; a typical Word-file also contains attachments like pictures, and links to those embedded blobs.
dennieku wrote: Is there a method available which saves the whole file to a stream or converts it to a byte array?
Yes, the <a href="http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpackage.close.aspx">Close</a>[<a href="http://msdn.microsoft.com/en-us/library/documentformat.openxml.packaging.openxmlpackage.close.aspx" target="_blank" title="New Window">^</a>] -method, according to MSDN;
Saves and closes the OpenXml package plus all underlying part streams.
Once closed, read all the bytes from the file and delete the original.
Bastard Programmer from Hell
|
|
|
|
|