I just inherited a C# windows application codebase. It's a relatively large application with lots and lots of UI "elements" that I believe may have been added by the previous developer with little to no interaction with the actual clients. This application is a robotics control system, it runs at a manufacturing facility, and it has some of the most complex UIs I have ever seen (forms inside of forms inside of tabbed elements inside of etc...)
One of the first things I want to do, is learn about how the actual plant floor associates interact with this application. I have already sent out a survey to the different supervisors, but I would like some empirical data as well.
What I would like to do:
I would like to somehow, capture every time a user presses a button, control, etc... and record it to a file. Something simple like:
timestamp,name of control,any other cool data I can capture (program run state, for example.)
The difficulty is that I'm not really a C# expert at this point, and I can't figure out the appropriate way to add some sort of global behavior to my application which does this, and doesn't impact existing functionality. Any advice would be greatly appreciated.
Global keyboard and mouse hooks would be the way to go. Unless someone knows the design thoroughly and can comment how to extend existing functionality. it is going to be bit difficult.
Related
Question:
Is there some effective way to hide some portions of the WinForm/WPF desktop program based on user settings/permissions?
Why I need this?
I'm starting a big accounting project which will contain hundreds of forms/dialogs.
The program is going to launch a main window which shows 1 to 4 divisions. The user selects each of those and it will then launch the a window which contains a sidebar with a bunch of buttons on sidebar (something like Microsoft Outlook). Now, when the user clicks on each of these buttons, it will open that section of the program and the user will work with that part. Based on the user permissions/settings, there's a need to sometimes hide some of these buttons though. For instance suppose I have 4 main divisions A, B, C and D. When you launch A, you'll get a sidebar containing A1, A2, ..., A100. A user might opt to see only A1 & A50!
Our initial approach was to use WinForms for this because the team was very familiar with it. I suspect that for doing so, we have to build some sort of model which contains information about user preferences and write lines of code like btnA1.Visible = false; a lot.
Frankly just thinking about doing that disgusts me. That's why I'm looking for a better way to achieve such result. I've searched around and found PRISM.
I'm not sure just yet but I think to use PRISM I need to make each of those buttons or their dialog a module and load them after I decide which of them is needed for the user.
It seems like a nice way to do this but considering the fact that this project is very urgent and we don't need to load different modules for different users (we just need to load them - ideally on demand - and sometimes hide some), I have some concerns:
My team might need some time to learn WPF
All of us don't know much about Unity and PRISM.
This might be overly complex, i.e. there might be a more simple way to achieve this without going into such lengths.
Also, I'm watching Prism & Silverlight Series and PRISM5 for WPF from Channel9.
a window which contains a sidebar with a bunch of buttons on sidebar (something like Microsoft Outlook). Now, when the user clicks on each of these buttons, it will open that section of the program and the user will work with that part.
That sounds to me like a TabControl. You'd rather not try to reinvent the wheel as it's already been invented.
The only difference between that example and your requirement is that instead of hard coding the tabs you're going to bind to a collection of ViewModels, like this, and then have each instance of TabViewModel toggle it's own IsVisible property depending on user permissions / user selections.
Simple as that. No need for complex MVVM frameworks. No need for silly obsolete useless winforms stuff.
I've been struggling for a long time with basic controls that Windows Forms offers to developers, but... right now, I am developing an application that requires more advanced control than normal "TextBox".
Since, at this time, my application is about memory management, I have to show in the form, the process memory in bytes (or other type of data) to the user, giving it the ability to modify it as he wants.
The problem comes here, because... if I show the data in a TextBox, it only allow me to display the data in read-only text because if I let the user modify the textbox directly, it will be very messy and unaesthetic.
I was reviewing some projects on SourceForge about C# and the handling of hexadecimal data, and i found a good project, called Be.HexEditor, which has a control developed and designed by its creators, but in GDI+.
The control is called HexBox, and that's just what I need to get.
Do any of you know how to develop a control like this?... I would greatly facilitate things. What kind of manuals/books should I read to learn this kind of development? I ask this because I ignore everything about GDI+.
Or... is there other way for do it?
I would use a textbox to show to the user the current value and another textbox to enter the desired value (maybe a slider will work better).
I think you'll find it's GDI+ that you have to learn
http://www.amazon.co.uk/GDI-Programming-Creating-Controls-Programmer/dp/1861006314
You may still be able to write controls in WPF and then include them somehow into your winforms app, but if you need to push pixels GDI+ is the only way.
I normally code with PHP, I am used to opening up my editor of choice and going away at it, coding classes,methods, etc. It is fairly easy as there is no GUI to worry about.
Last night I spent the whole night following a couple tutorials with C# in Visual Studio, it's turning out to be harder then I thought it would be. Once thing that I am not use to is, all the tutorials have you add a form object like a text box or button, then have you double clikc it to get to the code part, you then enter some code for that method. Then back to the form and re-peat
This seems very hard as you are never really working on "just the code" so 1 question is, is it always like that or just because i'm new and following tutorials?
Another question, when I see source code online to do certain functions, say I see a class I would like to try using, how can I use that class in the existing form class created by VS, do you somehow import other classes or do you add them right to the form code you are working on?
I'm sure that didn't make much sense but hopefully it does to someone, i'll try wording it better if not.
I should add that this was with WPF, also I feel like you have to learn 2 languages, the C# which has very similar syntax to PHP so that doesn't seem too difficult and the for GUI that's like a whole diff language
You can download the classes you are interested into.
Then you go to the Solution Explorer panel and you add existing items.
This will COPY the files to your project.
In order to use those classes you need to declare that you wan to use them.
So, what you have to do is to say something like
using FooNamespace;
Then you are ready to use the classes.
The name space is declared right before any class. You can go edit it.
Now about the forms. Each form is a Class and it consists of three files
ClassForm.cs
ClassForm.designer.cs
ClassForm.resx
You ONLY need the first one. Right click and view code. You can go there and use it.
Many questions, Many answers
Difficulty and Repetition
you can add form objects via the designer or you can hit the source button (CTRL-PgDn). From there you can edit elements in asp and html just like any php IDE. I do most of the work in source. I am a real programmer so I can never do the drag and drop. With intelligence and time you learn the properties and what to do.
to make complex pages you just have to know what you are doing.
What I started with VS I had the same feelings as you, but i have gotten into the flow of it.
As far as the code behind, you are just hooking methods up to the asp elements that get called by the built in code. You can add your own classes, functions, everything in the code behind or in separate files, just like c++, php, whatever.
Hope that helps, VS is really powerful and runs smooth when you learn where things are, been using it for years now and I'm still learning. Bottom line, never use drag and drop and just play with it.
unfortunately the .net world love drag-drop controls. so most tutorials are designed around this concept. drag a textbox on the to form. drag a button onto the form. double click button image to get the click handler.
it's not needed, it's just the approach for most people using visual studio. being that this is a WPF project everything can be done from code, or xaml markup. you don't need the WYSIWYG editor.
as for adding/referencing classes first you need to reference the assembly the class is located in. your core .net types (part of the BCL, base class library) are automatically included as references. then you add a using statement to the appropriate namespace. then you can instantiate the object.
There are ways to have a C# interactive window; see this question. Alternatively, you don't need to use a form, but you could also create a command-line application.
As for the second question, you can add a new class to your project and then use it in your form. There's really no additional step, except that if the namespaces are different, then it is easier if you import that namespace (via using).
Partly, yes, because you're new and using tutorials.
Partly, no, because you're working with forms, and you really don't want to hand-code those by hand.
If you just want to play with C#, and not concern yourself with forms and display, look for information on Console application. Instead of worrying about buttons and textboxes, your worst nightmare will be Console.WriteLine();
Here are some console-based C# tutorials:
C# Station tutorial
C# Yellow Book - it's a PDF. It's good.
Yes, it is exactly because you are following the video tutorials which are almost always tailored for beginners... Most of us making a living working in VS, developing WPF solutions do not even use the visual editor but instead work directly with XAML to build our UI and have very little or no code in the code behind files following the MVVM pattern.
To answer your second question, most of your classes that "do stuff" which is not directly intertwined with the UI should be in a separate class library (dll file) and should not even be referenced directly by your main UI project (in order to facilitate loose coupling) but instead accessed using some form of Dependency Injection, typically utilizing Interfaces.
The code that responds to user interaction should be in your ViewModel classess which are typically a data context for your views and these VM classes are typically using service agents which implement different Interfaces in order to use code stored in the class libraries mentioned in the previous paragraph.
Now, it is possible to just double click on a button and write all your code in that method created for you in the code behind file just like with Winforms, but just like in the Winforms world that leads to code that is hard to maintain, that is tightly coupled to your user interface and very difficult to test so try to resist that instant gratification and invest some time in learning the MVVM pattern, DI and OO design patterns which facilitate code reuse, decoupling and testability...
Hope this helps...
It really depends on what you are trying to learn. I don't think I would start off with WPF if I was using C#. I would start off with a console application to get the basics of the language down, then move down to a simple WinForms application, and finally to WPF where you started.
But yes, your questions about how the editor works is correct. It's how that platform works.
I'm writing a WinForms based application for Windows Mobile, targeting the CompactFramework 2.0 and coding in C#.
My application has a menu which the user can select severeral job functions from.
My question is this:
For the job specific screens, should I load a UserControl into a panel in the main form, or is it better to open a new form on top of the main form?
They both seem to meet my needs, and I don't know if there is a "right" answer here.
Is one method more correct than the other?
Forms are Controls (just look at the inheritance chain), and a Form itself doesn't have a whole lot of overhead in and of itself. It creates a native Window, but that's about it.
What should drive your decision is how you use and display your UI elements in your solution. Forms are conducive to many UI architectures, and they're what most developers are familiar with. The designer supports them well, and creating, showing, hiding and closing Forms is a well documented, often used paradigm that works just fine. Yes, you have the load penalty whenever a Form is created as it creates all of its contained controls, but you're going to pay that even if it's a UserControl. The child controls have to be created in either case.
One might argue that Forms require that you recreate them every time, but that's not true. If you use ShowDialog or Hide instead of Close, you can reuse your Forms and pay the price once. The advantage here is that the Form holds your Controls in teh collection and manages all of that for you, so you have little to worry about with the GC and remembering what roots you have alive.
The UserControl paradigm is more complex - you have to manage loading and unloading controls yourself to keep memory pressure low. Complexity also increases cost - cost to maintain, cost to support, and likely cost to develop. However there are some clear advantages to UserControls in some scenarios too. If you use an MVC/MVP pattern and some form of framework that handlesyour Views, a USerControl makes a really good View with the Form becoming the Workspace (the SCSF for the desktop is a classic example of this, and so is the OpenNETCF.IoC framework for the CF).
So which is "better"? It depends on how and where you're using the elements, how your team is already doing development, and how you've architected the solution you're plugging in to. In short, the is no one right answer.
In my experience, depending on your hardware, loading controls far outperforms launching distinct forms. Our devices (Motorola WT4090 with 32meg) have no hardware acceleration, and drawing complete forms seems to really tax them. There is as much as 4-6 second delay any time a form is launched; controls, however, are almost instantaneous.
Maybe the best answer is to create a series of user controls and experiment with loading them onto the main form. It should be a fairly easy matter to then try to create a series of forms that have just the user control to see if you can improve performance.
If you don't see any performance benefit either way, it seems that it would just be a matter of preference.
Use Forms. It's the way the other applications behave. It's the way the user expexts your application to work.
Look at the pre-installed "Contacts" application: On startup you get a contact list. Once you select a contact, a new form is being opened on top of the current window. It's showing all the contact's details. Selecting "edit" from the menu will open yet another form, allowing you to edit the contact. The "Tasks" applicatoin behaves just the same way.
So the user knows: Clicking somewhere will open up a new form, and closing that form will get me back to the last form. You should work with that knowlegde rather than against it. When you use a single form, the user might repeatedly close it while he actually wanted to get back to tha last form.
From a performance point of view I find that forms open fast enough (<1 sec) on my WM 5 and my WM 6 devices.
And while it's possible to achieve form-like behaviour with UserControls, it seems more straitforward to use forms when you need form-like behavior.
So my bottom-line is: Use Forms!
P.S.: There's a good article on CodeProject on : How to create MDI Application in Compact framework
Depends on the complexity of the form/Control. Going the UserControl route will provide better performance as you will not have all of the form create functionality to also deal with.
My advice is to create a new Windows Form for every different logical action. If you need a form that is logically independent, then is better to have a separate Windows Form for it.
To speed things up you could construct all your forms in application's start up. This way you will have a delay when your application is launching (most users will be OK with this), but afterwards everything will run faster.
I'm working on moving a client/server application created with C# and WinForms into the SOA/WPF/Silverlight world. One of the big hurdles is the design of the UI. My current UI is MDI driven and users rely heavily on child windows, having many open at the same time and toggling back and forth between them.
What might be the best way to recreate the UI functionality in an MDI-less environment? (I've no desire to create MDI functionality on my own in WPF). Tabs? A list panel that toggles different controls?
Look at 37signals and how nice their web UIs are (mostly HTML + AJAX). It's a good example of web applications that work. One of the things to remember are to make sure you don't break the web paradigm. If users want to see two things side by side, they should be able to duplicate the window and let the web browser do the windowing.
For WPF, there are a lot of new visualization paradigms. You can find some examples on the sites for various control toolkit providers: Xceed, Telerik, Infragistics. They have demo programs for the different ways they help you organize screens in an application.
When developing complex composite applications in WPF, you could also start at the Patterns and Practices Prism site. It's an InProgress set of practices for planning and developing complex composite (smart client style) applications in WPF.
I think the answer is really going to be up to your users -- I'd set up some prototypes with multiple paradigms and let them provide some input. The last thing you want to do is introduce a new UI paradigm without having any end-user input.
Tabs are really popular now, but don't allow side-by-side viewing, so if that is a requirement you may want to go with more of an outlook-style setup, with multiple panels that can be activated, hidden and resized.
One thing that you might want to do is to code your app as a composite UI, where each view is built independently from its container (be it a child window, tab or accordion, etc.), and is just "dropped in" in the designer. That will protect you from when the users change their minds about the navigation paradigm in the future.
multiple top level windows are easy to implement and have all the advantages of MDI - that's what MS selected for the newer versions of Office
Did you try GOA WinForms?