|
Jacob Barton wrote: My biggest question is how should I store all of the program data the user
enters
In terms of the application and what you described it probably doesn't matter.
What you should do however is create a persistence layer. That layer is ENTIRELY responsible for taking your data and storing it and retrieving it.
Then you implement one or more of the following.
1. A persistence layer that stores it in xml in a file.
2. A persistence layer that stores it in file using your own format: binary or text.
3. A persistence layer that stores it in some database.
Ideally you should have 1 or 2 along with 3. If you cannot switch them out without modifying the rest of your application (and no tricks involved) then your persistence layer is not clean. Otherwise it is good to go.
|
|
|
|
|
Jasmine, thank you "design pattern" is the terminology I was chasing. I have done an intro into programming course at Uni where they introduced this and I have created a few smaller applications using this approach. Web frameworks like Django have recently made me more aware of how powerful serparating the different layers of your application can be. Thanks for the links.
Gerry Schmitz wrote: I would consider using Windows Presentation Foundation (WPF) instead of WinForms; I think you'll have better results and better resources.
Gerry, would you mind elaborating on this a little if you don't mind. I have searched winforms vs. WPF to death and from what I can tell data binding and visual effects/appearance seem to be the highest selling points. Every article is almost the same "winforms will be around for a while to come, WPF is **better** but be prepared for a steep learning curve.". I have thought of using WPF so I can use WPF 3D instead of OpenGL but I am unsure.
jschell wrote:
What you should do however is create a persistence layer. That layer is ENTIRELY responsible for taking your data and storing it and retrieving it.
jschell,
What I am thinking of is having a DAL to retrieve and add to my database (application file). By doing this, I assume I will only need to store node / member information in the database (i.e. there is no need to store them inside the application as members of a class etc, just query the DB when their properties are required for drawing on screen etc). If I do this, do I need this layer you mentioned? I can understand it would be useful if I had everything wrapped up in my own class and just needed to read / dump to file on file open / save events. I will try goggling for persistent layers and see what I can learn on the subject.
Thanks all for you advice so far - Jake
|
|
|
|
|
It tends to help to have an abstraction to represent anything more conceptually complex than a single number. That way, you can talk about a "node" and its properties in your code, for instance. This would let both the drawing code, the calculating code, and the storage code work with a node, and not worry about where the data comes from or is used, other than what those modules need.
Assuming you have a structure with a number of nodes, members and loads (all interconnected objects of different classes), you'd retrieve this from storage, and build it up in memory. In this case, it doesn't matter whether the storage is a database, an XML file, or the pattern in a scanned-in image, as long as the storage layer knows how to extract the data. And the storage layer is only concerned with storing and retrieving data, not how it's used.
Similarly, the drawing module would only need to know how to translate your model to points and lines the rendering engine can use, so it wouldn't need to know how the model was created.
If you were to retrieve the data needed for drawing every time it's needed, it would be very inefficient and slow, and it would make it much harder to change storage method (for instance, if you decided to set up a department database with shared models).
While I'd warn against object orientation frenzy (which is where everything is shoehorned into a huge inheritance framework whether it fits or not), it might be a good idea to read up on encapsulation and abstraction and object-oriented design (I tend to recommend Grady Booch's "Object Oriented Analysis and Design" as the go-to book).
|
|
|
|
|
You'll want to use OpenGL - it's a standard in the industry, and using OpenGL will make your code more portable. Also, when building applications of this size, it is important to work from a priority list - and I mean actually write it down. Figure out what is most important, and put your effort there, and use frameworks and RAD tools to do the rest.
Since the interface isn't the important thing here, I would suggest making the interface very simple and using WinForms - it isn't worth it to you to go and learn WPF for this project because the visual interface part will probably be the easiest part of the app, and it's the least critical part too. The calculating of your results is where you want to focus your efforts. You have a large set of objects to design, and you need to focus on that. WinForms will let you design a good interface without putting a lot of effort into it.
On Data Access Layers - this is a design pattern, though there's many names for it. You will almost always create a DAL of some sort. For this application, I personally think you should go with some kind of Object-Relational mapping (another design pattern), such as the Entity Framework. With EF, you can do things two ways, database first or code first. So, you can design all your objects in C# code, then the Entity Framework can build a database for you, to store those objects. You can go the other way too - design a database and the EF can write C# code for the objects defined by the database. As you can see, this lets you focus on the important things about your data, instead of the "trivial" wiring between your app and the database. Object-Relational mapping is a known thing - let the machines do it.
Almost every modern application has a database of some kind, and for many years it's always been a relational database like SQL Server or Oracle. However, for "big data" and repetitive but small calculations, it may be better for you to use a "No SQL" type of database such as Hadoop - but I personally don't think your data will be "big" enough to warrant that. Either way, if you build your data layer as a separate module, you can swap it out later if you need to. That is the primary purpose of a separate data layer - to isolate the rest of the application from the mechanics of dealing with the database server. So basically, to answer your question, YES, you always need a data layer. Whether it will be implemented by a SQL server, No Sql server, or file system is unknown at the moment, but there will be a persistence layer of some kind for your data so you can save and load. It is important to think of it as a separate layer right from the start.
I'll let you do the Googling (EF, ORM, No SQL, etc), but are you starting to understand why apps like this are typically built by teams?
Oh also, please "reply" to our messages - I would have missed that your discussion was continuing because if you don't "reply" to us, we don't get emails. I came back here because I found your question interesting and well-stated, and that's rare.
|
|
|
|
|
Jacob, regarding WPF:
There might be a steeper learning curve with WPF, but only if you’re already steeped in WinForms. Because the “layout” model (XAML), wiring, and types of controls can be different from WinForms, it requires a mind-shift (like procedural versus object-oriented versus functional). If you’re “clear” or open-minded, picking up WPF is a lot easier.
(You’re also going to find a lot more graphics samples in WPF that you can use as building blocks; I would never suggest starting something completely from scratch. The Windows SDK will also have WPF samples).
WPF “Binding” might be (a little) difficult (because it is more flexible), but if you’re doing “graphics programming”, you will probably be less concerned with binding; you’ll will mostly be manipulation and animating graphics objects via code and “story boards”; WPF has better animation support (using “story boards”) than WinForms.
WPF has better built-in graphics support via “shapes”, “paths”, “brushes”, geometry, rotating, transforming, cameras; i.e. it is more object-oriented when it comes to graphics than WinForms; with WinForms, you are more-or-less working with pixels (IMO).
I started out with WinForms; pooh-poohed WPF at one time because it did not have a native “grid” (at that time); then was hired a few years ago to do a SCADA application in WPF, and have never looked back.
|
|
|
|
|
I would definitely echo Jasmine2501 comments on design patterns.
If you have time get yourself, and read, a copy of this book Headfirst Design Patterns[^].
It is easy to read, has lots of examples(in Java but, heck Java is virtually C#) and is not one of those university computer science style books, and well explained introduction to design patterns.
The reason I recommend this is once you get your thinking working along the design patterns route you will probably find that all the coding falls into place(my probably over-simplistic take on design patterns...).
“That which can be asserted without evidence, can be dismissed without evidence.”
― Christopher Hitchens
|
|
|
|
|
If you are going to use a database, SQL-Server is the most reasonable for a .NET application since it has the best .NET support. SQL-Server Express is free. Of course there is not much reason in putting it in a database if you are not going to be accessing the data from a computer. You can also just append the information in a text file.
|
|
|
|
|
Thanks for all the replies team. Seems I have a bit of reading to do before I get started.
Best regards,
Jake
|
|
|
|
|
Hello Experts
Here it is my scenario:
My Windows Application loads a web page using WebBrowser; Then Searches for online users and sends them a same message.
My Problem begins when I want to pass string to the specified element in the webBrowser.
My C# Code is:
WebBrowser.Navigate(string.Format("facenama.com/{0}", "user_name");
HtmlElement element = WebBrowser.Document.GetElementById("message");
element.SetAttribute("value", this.Message.Text);
WebBrowser.Document.InvokeScript("postform_submit");
The Html code of the element that sends the message:
<a href="javascript:;" id="postbtn" onclick="postform_submit();">
send
</a>
The above code does not send message to specified user.
What I am missing?
modified 17-Apr-13 4:32am.
|
|
|
|
|
After the script has run, you WILL have an attribute named "value" which contains your message. If you open up the Chrome debugger and check that element, you should see the value. However, the browser doesn't know what to do with that. It just thinks it is a generic attribute - like, one you made up, that doesn't have a special purpose.
In order to make the message show up, you'll want to set the "InnerHtml" of the element you are updating, or set up a JQuery event which looks for changes to the "value" attribute of your element, and does something to display it. Without knowing more about the look and feel of your app, it's hard to say which method would work the best.
Bottom line is, "value" is meaningless to the browser as an attribute of the A tag. So, it's probably setting it, and you should check that with your browser tools. The problem here is you're using a client-side element and treating it like it's a server-side TextBox control or something, in which case "value" or sometimes "text" is the field you set to display things. Your client-side elements don't work that way.
|
|
|
|
|
Thank you for your advise.
There is an odd problem.
Now the code sends the message and the webBrowser show message that your message sent successfully but when I open the target profile there is no message from me. (The target profile is mine too, but they are not same.)
SignatureNotFoundException
|
|
|
|
|
Impossible to say from the information given. Please take a few minutes and read the post about how to ask a proper question. I wanted to help you here, but I can't. Please read and understand the document at the link...
http://www.catb.org/esr/faqs/smart-questions.html[^]
|
|
|
|
|
The problem has changed!
I have signed up twice; The first one for sender and the second for receiving the message.
When I send a message with these two account; The message will be send. But when I change the target account name the message won't send; but it is in my own account.
|
|
|
|
|
If you're trying to make a screen-scraping spam machine, just say so. Otherwise I have no idea what you're trying to do here. The email providers deliberately make it difficult for you to do this kind of thing, because the users don't like it. It's going to be hard to do.
|
|
|
|
|
The other thing to look at is this line:
WebBrowser.Navigate(string.Format("facenama.com/{0}", "user_name"); Are you sure you didn't mean to say this:
WebBrowser.Navigate(string.Format("facenama.com/{0}", user_name); Because the first version always generates the same string...
The universe is composed of electrons, neutrons, protons and......morons. (ThePhantomUpvoter)
|
|
|
|
|
For now I didn't put this code in the loop.
Why would I do that when I am not sure about the single one?
|
|
|
|
|
Your code doesn't work. *and you don't know why*
Why bother asking a question if you ignore advice.
"It's true that hard work never killed anyone. But I figure, why take the chance." - Ronald Reagan
That's what machines are for.
Got a problem?
Sleep on it.
|
|
|
|
|
This is kind of for my own entertainment, but I was about to say "the second thing is better" to someone, but now that I think about it I'm not sure...
Option 1
public class MyClass {
private System.String SettingValue = "";
private System.String SETTING_KEY = "SomeSettingKey";
public MyClass() {
this.Server = System.Configuration.ConfigurationManager.AppSettings[this.SETTING_KEY];
}
}
Option 2
public class MyClass {
private System.String SettingValue =
System.Configuration.ConfigurationManager.AppSettings["SomeSettingKey"];
public MyClass() { }
}
My reasoning is that the setting key is only ever used in one place so creating a constant is unnecessary overhead, and secondly, there is no reason to create an empty string, then discard that string to the garbage heap, then set it to the value you really wanted... just set it to the correct value on instantiation.
|
|
|
|
|
Jasmine,
The use of a named constant is preferred, even if it will be used only once.
Will the value from the AppSettings be the same for every instance of MyClass?
If so, then Option 2a with the addition of static readonly :
public class MyClass {
private const string SettingKey = "SomeSettingKey";
private static readonly System.String SettingValue =
System.Configuration.ConfigurationManager.AppSettings[SettingKey];
}
If you need the SettingValue to match the AppSettings value when each instance is created, then I'd scope as much as possible within the constructor:
public class MyClass {
private readonly System.String SettingValue;
public MyClass() {
const string SettingKey = "SomeSettingKey";
this.SettingValue = System.Configuration.ConfigurationManager.AppSettings[SettingKey];
}
}
|
|
|
|
|
If I had given you the real name of the class in the code I'm working with it would be obvious, but yeah the setting value and the key can not change for the life of the application. In fact, I think the class might actually be a singleton for our app but I need to discuss that first with the previous developer. Once it's read, it's always the same, so I think the "static readonly" is the right modifier for it. Thanks for the help, that makes a lot of sense
Also, I know it's excessively trivial, but my objection to the named constant is - wouldn't that take a memory location we don't need to use? The compiler doesn't know that it will only be used once, so it's going to stick that in a memory location, right? So then, what we have is two instances of the string in memory, right? Once in the code and once in the heap? If you do this a thousand times, you waste a K of memory. I know, I know, who cares about a lousy 1K of memory...
(programmers not giving a crap about saving 1K of memory when they can is probably why my favorite pinball game no longer works well on my tablet, and I find it annoying. I find the bloat in modern software really annoying, even when it doesn't cause bugs or performance issues)
|
|
|
|
|
I'd probably use a const, but have you considered using an enumeration?
Jasmine2501 wrote: wouldn't that take a memory location we don't need to use?
Possibly, but that kind of thinking can lead to define s -- at one place I worked (in C) the standard was to put such values in define s to "save space".
|
|
|
|
|
But that doesn't really save space, right? Using #define puts the literal value into your final code, right? So, if it's used in multiple places, you're actually wasting memory (code size) with #define, but only if the value is used more than once.
|
|
|
|
|
The const for the string is really the better way.
Remember that in c#, strings are invariant. So the compiler can and will automatically use the same actual string no matter how often it is referenced. Referencing a string const multiple times, or using the identical string literal multiple times is the same. Only one string will be stored in the program and all of the references to it will be to the exact same object.
So why did I say the const for string is better?
For maintainability. The name of the const can (should) be based on the functional use of the value, and can be updated in a single location, guaranteed to affect all uses. With string literals it is easy to miss one
|
|
|
|
|
Yeah I agree, I just thought since the string was being created as an object, it's going to get stored in memory somewhere, in addition to the place where it's stored in the code.
|
|
|
|
|
But no matter how you code it, const or literal, it must be an object at run-time!
The compiler arranges for it to always be the same object.
This is from the c# spec document:
For instance, the output produced by
class Test
{
static void Main() {
object a = "hello";
object b = "hello";
System.Console.WriteLine(a == b);
}
} is True because the two literals refer to the same string instance.
|
|
|
|
|