Mav3rick
Mav3rick

Reputation: 774

Need help creating control to display data

I am writing a .NET WinForms application that needs to display a list of results in a nice formatted user-friendly fashion. Here's how I'm hoping to display the data.

alt text http://img398.imageshack.us/img398/4336/imgdyu.png

The table must support a decent amount of data(>= 200 individual "data blocks"), and needs to be fairly fast. I'm unsure of the easiest way to accomplish this and I was hoping for some direction and advice. I created a quick prototype custom control that simply used a bunch a text boxes stacked on top of each other. It worked fairly well but Windows runs out of handles for the textboxes too quickly. I could create a custom textbox control, but it would be time consuming and I was wondering if there are any recommendations for alternative solutions? Thanks.

Upvotes: 3

Views: 1412

Answers (8)

MusiGenesis
MusiGenesis

Reputation: 75346

You could use a third-party control for this (maybe), but here are some reasons why this is potentially a bad idea:

  1. third-party controls cost money
  2. third-party controls tend to suck
  3. third-party controls require you to distribute at least an additional DLL, over which you usually have no control
  4. even if the third-party control can ultimately do what you need, it will take you some time and effort to figure out how to use it, and how to hammer it into the shape you require

For anything out of the ordinary (like what you're doing), writing your own UserControl is the best way to go, for these (among others) reasons:

  1. writing your own UserControl is far and away the most fun thing you can do in .Net
  2. you will have to learn some things to do this well, but the knowledge you gain is immediately transferable to other problems and projects (whereas whatever you learn about using Initrode's Infinite Wonderfulness Gridifier will only ever help you with using that particular control)
  3. there will be nothing additional to distribute with your application
  4. complete control over the source code
  5. free forever (with apologies to Evony)
  6. the sky is the limit - with any third-party control, you will ultimately run into something that it just can't do, but if you're doing it yourself, you can literally do anything you want

Your particular problem (well described in your question, thanks to the graphics) is quite easy to do as a mostly owner-drawn UserControl (with a TextBox or two thrown in the mix). The only methods you'll need from the System.Drawing.Graphics object are DrawRectangle, FillRectangle, MeasureString and DrawString. You won't even need any documentation, as Intellisense will give you everything you need.

If you run into trouble, I'll write it for you for a chocolate chip cookie. :)

Update: since you need the text to all be selectable, that makes this approach a bit more complicated. Implementing your own Textbox-type functionality is a gigantic pain in the petard, but a relatively simple solution is to add a real multi-line Textbox over top of any text-containing rectangle when the user clicks on it, and to put the rectangle's text (pre-selected) into the Textbox. When this temporary Textbox loses focus (LostFocus), you draw the edited text into the rectangle and delete the Textbox. This way you only have one Textbox at a time in your UserControl.

This version will cost you two cookies.

Update 2: Here is a simple application that demonstrates how to use a single TextBox to make your entire control selectable and editable. And here is the source code.

Upvotes: 3

Daniel Mošmondor
Daniel Mošmondor

Reputation: 19976

To me it seems like a great exercise in controls that are self painted. Instead of creating textboxes, override/subscribe to OnPaint event and use Graphics object to DrawString() in appropriate places, DrawRectange() to have rectangles around them. If you know the position for your textboxes, existing code will be fairly easy to convert.

Some advice:

  1. for first version: don't bother with limiting your drawing to visible portion of the control (I guess you'll need some scrolling here)
  2. for (1) - graphics will do the clipping for you, and you can take care of it manually once you confirm that you have right layout and right data on the screen
  3. use double buffering to reduce flicker by all means
  4. use sunscreen

Feel free to comment with further questions...

Upvotes: 0

Will Marcouiller
Will Marcouiller

Reputation: 24142

You may want to publish an EditingControl property to your object if you wrote it yourself, and create a new instance for each instance of your class retrived from the database.

someObject.GetList().ForEach((so) => {
    ConstructorInfo ctor = so.EditingControl.GetType().GetConstructor(new Type[] { });
    var editingControl = ctor.Invoke(new object[] { });
    editingControl.Name = "someName" + ++counter.ToString();
    editingControl.Location = new Point(posX, posY);
    editingControl.Width = someWidth;
    editingControl.Height = someHeight;
    editingControl.DataSource = so;
    myForm.Controls.Add(editingControl);
});

Well, I hope you may get the idea. This is not very optimal as a solution, but rather good anyway, in my humble point of view.

Hope this helps!

Upvotes: 0

Will Marcouiller
Will Marcouiller

Reputation: 24142

I don't know the nature of the datum you wish to display, but for fast accomplishment, the System.Windows.Forms.DataGridView does the job well and is embedded in .Net Framework 2.0.

If you're used to work with Linq to SQL Classes, if you're using SQL Server as the datastore, just create your DBML diagram and:

  1. Add a data source ;
  2. From the Data Source tool window, select the display as grid, and drag-drop it on your form ;
  3. Edit the columns and reorder them as you want them to be displayed for your client ;
  4. In the code, set the DataGridView.DataSource = someObject.GetList() which will return an IList of the object you wish to display in this grid.

This only requires about ten lines of code and a few Windows Forms design-time. I hope I didn't forget anything crucial. :-P

Please let know whether it helps!

Upvotes: 0

Isaac Abraham
Isaac Abraham

Reputation: 3512

Without knowing more about the sort of data, I think you want a user control which will be the "repeated" bit. You can use a TableLayout container control (or a FlowLayout perhaps?) and add / remove the items from the table as required.

If your data is tabular, perhaps with a parent / child relationship, I would say you should use a grid control. I don't agree with the statement of another answer here that you should steer clear of third-party controls. They will save you time very quickly - some, like Janus' GridEx control, costs relatively little (a few hundred quid) and will save you hours - which, if you work in a commercial environment, can translate to much more than the cost of the control. Plus they look much better and offer better functionality than the standard WinForms Grid control.

Upvotes: 0

AMissico
AMissico

Reputation: 21684

Will the DataRepeater from the Visual Basic PowerPack work for you? It is a download for VS2k5 and installed with VS2k8. If not, check the TemplateListBox at www.codeproject.com/KB/cpp/TemplateListBox.aspx and the ContinousControl at blogs.vbcity.com/hotdog/archive/2006/10/26.aspx.

Upvotes: 0

3Dave
3Dave

Reputation: 29051

If this is a web application:

Is this data editable in the page, or is it for display purposes only? If the former, consider making each item a link to an new editor page that would edit one block at a time.

If you are only displaying the data with no edit capability, use a repeater control to output an HTML table. Take a look at

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/ctrlref/data/repeater.aspx

The repeater binds to any datasource - a List<>, Array, DataTable, etc - and iterates through the contents, and displays the data for each row according to the template you specify in the aspx. The

If this is a winForms application

Ask yourself why your application isn't web based. There are (in my very humble opinion) very few apps these days that are better suited to winForms implementation. Graphics editors, compilers, etc are good examples. A reporting engine, however, would most likely be better suited to a web implementation. YMMV.

If you're still set on using WinForms, a better solution may be to use a label or other handle-free control for your text. Link to another form if you need to edit each entry. Any page that has thousands of textboxes will provide limited usability.

Upvotes: -2

Pierre-Alain Vigeant
Pierre-Alain Vigeant

Reputation: 23103

You could use the WinForm Grid control to achieve that, or any 3rd Party Grid or List components.

The WPF ListBox with a data template could also achieve a similar behavior.

Upvotes: 0

Related Questions