|
SomeGuyThatIsMe wrote: If you could rewrite the file using xml tags
Of course he can't change the school assignment.
---
b { font-weight: normal; }
|
|
|
|
|
why not? i always did. I didnt see anything about a school assignment, but i'm mostly blind, so i prolly missed it, and just assumed that it was for work of some kind...but the stream reader method should work, fairly easily, even if it is a bit slow.
|
|
|
|
|
I must select the "not very good way" and to open the file into a stream and use ReadLine() to grab each line and put it into a string, then fall through a switch on the first character so I know what kind of object to use
This part I know how to do it ... The don't know part is how to use the fields and C# classes to create this single object I need. Some one sent me some code in VB.NET that I think it seems like i need, only that I need it in C#. If you have something similar please send at least some explanations.
The VB code :
Private Sub ParseFile(ByVal filename As String)
Dim headers As New HeaderCollection
Dim reader As IO.StreamReader
While reader.Peek <> -1
Dim line As String = reader.ReadLine
Select Case line.Substring(0, 1)
Case "H"
headers.Add(line)
Case "I"
headers.LastItem.InformationList.Add(line)
Case "C"
headers.LastItem.InformationList.LastItem.Comments.Add(line)
Case "E"
headers.LastItem.Footer = line
End Select
End While
End Sub
Private Sub WriteFile(ByVal filename As String, ByVal headers As HeaderCollection)
Dim writer As IO.StreamWriter = New IO.StreamWriter(filename, True)
For Each h As Header In headers
writer.WriteLine(h.Text)
For Each i As Information In h.InformationList
writer.WriteLine(i.Text)
For Each c As Comment In i.Comments
writer.WriteLine(c.Text)
Next
Next
writer.WriteLine(h.Footer)
Next
writer.Flush()
writer.Close()
End Sub
Public Class Header
Private _informtions As New InformationCollection
Public Text As String
Public Footer As String
Public Property InformationList() As InformationCollection
Get
Return _informtions
End Get
Set(ByVal Value As InformationCollection)
_informtions = Value
End Set
End Property
End Class
Public Class Information
Private _comments As New CommentCollection
Public Text As String
Public Property Comments() As CommentCollection
Get
Return _comments
End Get
Set(ByVal Value As CommentCollection)
_comments = Value
End Set
End Property
End Class
Public Class Comment
Public Text As String
End Class
Public Class HeaderCollection
Inherits CollectionBase
Public Overloads Sub Add(ByVal Text As String)
Dim h As New Header
h.Text = Text
List.Add(h)
End Sub
Default Public Property Item(ByVal index As Integer) As Header
Set(ByVal Value As Header)
Me.List(index) = Value
End Set
Get
Return DirectCast(Me.List(index), Header)
End Get
End Property
Public ReadOnly Property LastItem() As Header
Get
Return DirectCast(Me.List(Me.List.Count - 1), Header)
End Get
End Property
End Class
Public Class InformationCollection
Inherits CollectionBase
Public Sub Add(ByVal Text As String)
Dim i As New Information
i.Text = Text
List.Add(i)
End Sub
Default Public Property Item(ByVal index As Integer) As Information
Set(ByVal Value As Information)
Me.List(index) = Value
End Set
Get
Return DirectCast(Me.List(index), Information)
End Get
End Property
Public ReadOnly Property LastItem() As Information
Get
Return DirectCast(Me.List(Me.List.Count - 1), Information)
End Get
End Property
End Class
Public Class CommentCollection
Inherits CollectionBase
Public Overloads Sub Add(ByVal Text As String)
Dim c As New Comment
c.Text = Text
List.Add(c)
End Sub
Default Public Property Item(ByVal index As Integer) As Comment
Set(ByVal Value As Comment)
Me.List(index) = Value
End Set
Get
Return DirectCast(Me.List(index), Comment)
End Get
End Property
End Class
Thanks
|
|
|
|
|
ick, i hate VB, mostly because the vast majority of examples you find for it never bother with strict typing, which if you're going to translate to c# is very necessary.
ok i'm going to assume that all this needs to do is read the file, then write that same data to a different file, i havnt messed with generics, but i would either make the "superclass" have properties of the other types, or make the other types like header or comment inherit the superclass, but i havnt messed w/ generics so there's prolly some slick, cool way to do this that i'm not aware of.
but to read the file in c# (you get to declare the varibles cuz i'm too lazy to type that), i'm also going to assume that the super class has properties of the type of the other classes so i can get to them like record.header.*something a header has or does*
while(!endOfFile){//endOfFile is a bool initialized to false
line = reader.ReadLine();//line is a string, guess what reader is
firstChar = line.SubString(0,1);//pretty easy so far right?
switch(firstChar){
Case 'H':
record.Header.value = line;/*record is an instance of the superclass, value is the property you want the header stored in, if you want the first letter gone you'll have to remove it with a line = line.Remove statement*/
break;
Case 'I':
//do whatever you need to do to save the information in the record object
break;
/*keep going until you've added everything for a certian record..if you can have mulitple comments the comments property of the record class may need to be an array or you'll have to figure out some other way to handle it*/
}//end switch
recordList.Add(record);/*adds the record object to an ArrayList of record objects..or you could use a normal array if you know how many records you'll have*/
}//end while dotn forget on case 'E' you have to set end of file to true so the loop ends
to write the file you'll just need a StreamWriter then just use a foreach loop to get your stuff back
foreach(Record r in RecordList){
writer.write(r.header.value.ToString());//so on and so forth, you'll have to so something speical for the comment part if you can have more than one...if you used an array or array list you can just loop through the comments like you are the records in record list
}//end foreach
and tada you're done...i think, i'm not gaurenting that this code will work( i wrote it on this site not in visual stuio and i havnt tried it, but the methodology does work i've used that several times before. if you need anymore help or have any questions shoot me an email to dalaji@excite.com(its my spam account so put CodeProject help or something like that in the subject so i dont delete you)
|
|
|
|
|
My biggest problems aren't the parser but the classes , the fields and propreties of those classes. At the moment I have the following classes :
Record ( which is the superclass )
- MessageHeaderRecord ( the superclass for the next classes ) :
- InfosRecord ( the class for the I tag
representing the informations from text )
- CommentRecord
- OrderRecord
- ResultsRecord
- TerminatorRecord
For each of this classes I have a corresponding class (MessageHeaderRecordFields ,...) in which I created the fields to put the infos from the file.
So far so good ...
MessageHeaderRecord beeing the superclass for the rest of classes I put inside of it a generic List :
private List<informationrecord> m_Infos = new List<informationrecord>()
internal List<informationrecord> Infos
{
get
{
return m_Infos;
}
}
and the constructor is
internal MessageHeaderRecord()
{
RecordType = RecordType.MessageHeaderRecord;
m_Fields = new MessageHeaderRecordFields(); //
}
I did this because I want to access the objects as follows :
Message MyMessage = new Message();
MyMessage.Infos[3].Fields.SequenceNumber = "1";
MyMessage.Infos[3].Fields.InfoName.LastName = "John";
// Create a new info
int nInfoIndex = MyMessage.AddNewInformation(); (*1)
// Set the info specific data such as name, age, etc. for the info we just addded
MyMessage.Infos[nInfoIndex].Fields.InfoName.LastName = "John";
// Add an order record for this patient
int nOrderIndex = MyMessage.Infos[nInfoIndex].AddNewOrder(); (*2)
// Set the order specific information for the new order
MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].Fields.OrderID = "11";
// Add a comment to this order
MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].AddNewComment(); (*3)
// Set the text for the new comment
MyMessage.Infos[nInfoIndex].Orders [nOrderIndex].Commment.Fields.CommentText = "I am a comment.";
// Add a Result to this order
nResultIndex = MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].AddNewResult();
// Set the new result's data
MyMessage.Infos[nPatientIndex].Orders[nOrderIndex].Results[nResultIndex].Fields.SequenceNumber = "333"; (*4)
So my problems redefined would be
(*1) - In which class to put the AddNewInformation() method
(*2) - In which class to put the Orders List and where to put the AddNewOrder() method
(*3) - In which class to put the Comment List and where to put the AddNewComment() method
(*4) - Same with Results List and AddNewResults() method
Please help me again with this issues because I really cant figure them out.
Thank you in advance
|
|
|
|
|
*1 you'd have to put the AddNewInformation method into the class that MyMessage instantiates(sp?) so since MyMessage is of type Message AddNewInformation would have to be in the Message class, or in the class that Message inherites. the same with the others...if you want to add a record to orders, then orders must implement that function, if you're sure you want to access the objects like this.
it looks like you want to access the rest of the properties like they're in a predefined array...if you want your Add** methods to work like the ArrayList.Add() method you dont need the [], just call the add function, using a predefined array isnt a very good idea unless you always know the number of the elements you'll need..and setting the array to be overly large is just a bad habit to get in. you could just have the comment, info, orders, etc.. classes store info about themselves and then have Record contain arrayList properties for each that way you can still use [] to specify records, and they'll be dynamically sized...and you could either put the Add*** methods in Record and just have them add new instances of the respective class to the list. also if you have the Add*** methods take a parameter or two you could save yourself soem typing at least w/ the coments, and set the text for the comment when you add it. this may be possible with the other add methods but i'd have to see your code. if this didnt help you could send me an email w/ some of your class definitions, thats about the only way.
Oh, if i'm wrong about something feel free to correct me, i'm mostly self taught and generally have a different way of looking at and explaining things, than most other programmers i've talked to, sometimes my way works better sometimes its way worse.
HTH
John
|
|
|
|
|
Ive been trying to figure this problem out. I have a status strip with a progress bar in it. I want to use that pb to increase as the file is copying. Someone suggested I have an event that occurs every few bytes or so to increase the pb. I have looked and looked for a way to do this only to return to not have anything. Any help or a link that can do this would be greatly appreciated. Thanks.
|
|
|
|
|
try to use the Refresh() method for your progress bar after each PerformStep()
regards..
.:: Something is Wrong ::.
|
|
|
|
|
With BCL classes you're out of luck here.
The built-in classes don't give you any progress update while copying.
You can either write your own file copy routine that's firing an event from time to time or p/invoke CopyFileEx .
Regards,
mav
--
Black holes are the places where god divided by 0...
|
|
|
|
|
In my app, Refresh() does the job..
But you can also try
..
..
//after a specific amount of bytes are copied
UpdateProgressBar();
..
..
public delegate void UpdateDelegate();
private void UpdateProgressBar()
{
if (statusToolStrip.invokeRequired)
{
UpdateDelegate delegate = new UpdateDelegate();
delegate.Invoke(UpdateProgressBar);
}
else
{
progressBar.PerformStep();
statusToolStrip.Refresh();
}
}
..
..
.:: Something is Wrong ::.
|
|
|
|
|
That's not the question.
How can you update the progress bar when you don't get any progress notification from File.Copy() ?
Regards,
mav
--
Black holes are the places where god divided by 0...
|
|
|
|
|
Hello
Pardon me for asking this intuitive question, but...
How do you copy your file exactly??
Regards
|
|
|
|
|
..
using System.IO;
..
..
File.Copy(source,destination);
..
..
.:: Something is Wrong ::.
|
|
|
|
|
Hello
Mav is right. Yet!! As my habit of making crazy suggestion;P, you can make a timer that checks the destination file's size each -let's say- 50 milliseconds, and updates the ProgressBar according to the percent of the current size/Total size.
Regards
|
|
|
|
|
its not an issue about refreshing, I dont know how to even make it invoke a way to update the pb after so many bytes written. I only know how to copy in general with File.Copy or FileInfo.CopyTo but neither of these provide a way to update a pb after a specified about of bytes and thats what i need to do.
|
|
|
|
|
Where is it? is it there or i am just wasting my time to find it out?
sorry for my bad English.
|
|
|
|
|
Hello
Never heard of it!!
Why don't you put a label above the DataGridView?
Regards
|
|
|
|
|
Hey guys, since i'm trying to do this from a c# windows app i'm posting here, even though this could go in a couple areas. What i'm trying to do is post to a website that will create a file...dont care about getting the file back, just need to send the WebRequest to the site, but i'm getting a System.Net.WebException error 401. I've checked IIS on the server and the site i'm trying to use is set up exactly like another site which i can post to just fine. (yes i realize that this seems like an IIS/permissions problem, but i've checked the settings 3+ times they identical) if it is an iis problem, a pointer to it would be greatly apprecieated. here's the code i'm using to make the request.
url is a string that i get from the app.config file right now it = "Http://<local server="" name="">:<port number="" of="" the="" site="">" i've also tried the server's ip. i specifiy a port number because this server also runs our mail program which has its own site that takes over port 80...we have several site running on machine all w/ different port numbers and they work fine..the port for this site is 877, its duplicate site(they each point to different databases, dev and testing) is 888.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method="GET";
request.PreAuthenticate=false;
request.GetResponse();
i've also tried POST instead of GET and i've tried a System.Uri object to create the WebRequest, and i've tried with and with PreAuthenticate. Oh, this is an internal use only app, so i'll always have access to this server, just thought i'd mention that before someone asks why i'm doing this.
Thanks guys,
John
|
|
|
|
|
Hi guyz,
I'm using C# for my program and Crytal report for printing of sales report but I got this error after packaging and testing of my program:
"Cannot find KeycodeV2.dll, or invalid keycode."
I'm using VS.net 2003 and I don't know if i'm missing something during the packaging or it is because of my VS version.
Please help...
Best regards,
Paul
|
|
|
|
|
I created a DataViewManager on a dataset here is the code:
obj = new CSIA.Controller.MembersFullView();
obj.Read();
DataViewManager dataManager = new DataViewManager(obj);
dataGridView1.DataSource = dataManager;
dataGridView1.DataMember = "Members";
dataManager.DataViewSettings[0].RowFilter = "[Member Number] = '1105'";
.....Members is the first table in the dataset
What I don't understand is that if I apply the RowFilter before setting the
DataSource I get a filtered view but if I put it after I get the full table.
I thaught filtering the DataManager would update the DataGrid as a DataView
would. Am I missing something ?
|
|
|
|
|
Hello
I don't know, but!! I guess your question is already self answering.
You've changed the filter of the DataTable indexed zero. You have to populate the view with that new filter.
That's is dont by either assigning to the DataSource property because it populates the records of the table through the already filtered view, or by using DataViewManager.CreateDataView() method
If someone knows otherwise, please post!
Regards
|
|
|
|
|
I have a thread (which is not the main GUI thread )that I want to be able to create a form using the Show method.
The thread basically loops for commands and responds to them. Some of the commands are to display a form - and then wait for the next command.
Now when I try to do this the Form freezes i.e. not responding. Now I assume that is because the thread is blocking waiting (Monitor.Wait) for the next command. I suppose this blocking prevent the GUI from responding to events.
So my question is related to this problem.
1. Is is good practice to create Form from a thread other than the main GUI
2. Can I do a for.Show method and spawn it into a worker thread?
All thoughts and suggestions would be appreciated.
|
|
|
|
|
Hello
LiamD wrote: Is is good practice to create Form from a thread other than the main GUI
If you want your working thread to be blocked by the shown forms, you can use it to show these forms. Simple, isn't it??
OTOH I don't think is what you want. So, simply make a thread for each form that is shown. The thread should be alive as long as the form is visible. Once the form is closed, abort the thread nd dispose it.
And yes of course!! Sometimes this is a good practice, depending on the structure of your program.
LiamD wrote: Can I do a for.Show method and spawn it into a worker thread?
I don't know what is a "for.Show" method, but you can -and probably should- show each form on its own thread as above.
Regards
|
|
|
|
|
I was concerned because i have never seen any examples of projects creating a thread for each form.
Can you please give an example of code for this? Something liek this ...
Form f = new Form();
t = new Thread(new ThreadStart(f));
t.Start();
I just want to make sure that I will not run into problem using this method when running in a multi threaded project.
By the way I meant to write Form.Show() method above.
Thanks,
Liam
|
|
|
|
|
Hello
Well, running into trouble in multithreading is as easy as slipping in the mud in a rainy day!! There are two scenarios. One if you want to keep track of each thread -for several reasons I suppose-. This is the hard way, so I'd rather skip it for now .
The easy way is to launch each thread and let it die as it finishes without tracking -Thank God for the GarbageCollector!!-. Here is a sample code:
private void button2_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
Thread MyThread = new Thread(new ThreadStart(MyThreadMethod));
MyThread.Start();
}
private void MyThreadMethod()
{
Form1 MyForm = new Form1();
MyForm.ShowDialog();
}
The Thread will die and get collected once the form is closed. Carful not to open too many forms though.
Regards
|
|
|
|