I'm writing a winforms application which stores its data as plain text files and presents it to the user as a multi-column list. I'd like the user to be able to sort and filter the list, and also to re-order and hide/unhide columns.
I thought a DataGridView would be a good fit since it has a lot of that functionality built in, but I'm going to need some cell types (a date picker for instance) that are not available out of the box with a DataGridView. I know you can host controls inside a DGV and have read a Technet article on it, but it seems fairly complex and I'm newish to C#, Winforms, and OOP. A DGV is also not the prettiest control, and even though I know how to change its properties to make it look somewhat nicer, it never gets to where I really like it. Appearance isn't a dealbreaker if it's the way to go, but it's a "nice ot have."
So my question is: should I be struggling through getting the DGV to do what I want, even if it takes me longer and is more frustrating to do, or should I be rolling my own custom control(s)? I've created a couple of user controls in the past and am fairly comfortable with that.
Brian is right in the comment above. If you want customization, WPF is the way to go. However, coming from a WinForms background and starting fresh with WPF will be a steep learning curve.
Writing you own DataGridView-like control from scratch I don't view as a viable option. Reflect the code for the DataGridView and you will see why, there are thousands of lines of code for this component. If you mean that you will override the DataGridView class then, cool, that is a good idea. If it is cell based controls like the data picker you want you may be better overriding/sub-classing the DataGridViewCell instead...
You can customize the appearance of the DataGridView to make it look good out-of-the-Box, but don't underestimate the amount of time it will take to sub-class/inherit from DataGridViewCell to make something like a DataPicker, it won't be that enjoyable, but of course possible...
You can get the filtering you require, by just binding the grid to a DataSource like a DataTable and filtering that. This will automatically filter the displayed results.
I would think about using an existing library for this, as you will be reinventing the wheel to a large extent. Of course most controls are commercial and not free; but there must be some that are...
I hope this helps.
I have been using Infragistics for a few years now. Their WinForms products are very good, and in particular, their win grid control sounds like it would meet your needs. You can even use their grid columns in DataGridView if you don't want to use their grid (their grid takes a little bit of time to get used to). Their controls are somewhat expensive, but it's there if it suits your needs.
A good alternative for DataGridView is SourceGrid:
https://sourcegrid.codeplex.com/
I tried a test with a calendar form I use for our system:
Private Sub dgvTaskLog_CellContentClick(sender As System.Object, e As System.Windows.Forms.DataGridViewCellEventArgs) Handles dgvTaskLog.CellContentClick
Dim frm As New frmCalendar
frm.ShowDialog()
If IsDate(frm.outSelectedDate) Then
dgvTaskLog(e.ColumnIndex, e.RowIndex).Value = frm.outSelectedDate
End If
End Sub
When the user clicks on the cell the custom calendar form opens. You would most ikel ned to do some checks on what column to just display the calendar (or other "control") for that column. Not sure how this works for tabbing around cells, you may need another event to pull it off.
The custom form hosts the VB.Net calendar control and adds local business logic. If a valid date is returned it is stuffed into the cell. If the grid is bound you would need to update the datasource instead.
Any way - just another possible option.
Personally, I would stick with the DataGridView in WinForms. Instead of making a date-picker cell type, I would instead consider just launching a new Form with a date-picker on it to handle the actual time/date entry into the cells. This would give you the customization flexibility you need while not adding complexity to the DGV. The DGV can be left mostly or completely as-is with just out-of-the-box functionality, and then you can build your custom functionality around it as suggested with the date-picker on your own custom form, for example.
Good luck.
Extending the functionality of a DataGridView isn't easy but can be done as I've done it before Report Manager. You can also create custom field controls. Perhaps it might be easiest to create a template field with your gridview and use the ajax calendar extender.
<asp:GridView ID="myGridView" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="myTextBox" runat="server" />
<ajaxToolkit:CalendarExtender ID="calDate" runat="server" TargetControlID="myTextBox" Format="MM/dd/yyyy" SelectedDate='01/01/2016'></ajaxToolkit:CalendarExtender>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Related
Sorry but I am a newbie to WPF, I would really appreciate if you could help me-
Tag 1 in pic- Which control can I use to create a menu similar to that in the picture ? The closest I came was using a gridview within a listview but that ends up using a header for the gridview. Normal listview just highlights the entire strip and doesn't look good at all.
Tag 2 in pic // (No longer relevant, sorry)
Edit:
Looking for something simple like when using gridview with listview (as in pic below) there is automatically that standard window gradient & bevel effect etc. (As an idea, implementing it with buttons seems to cumbersome, first strip button border, then create all these effects.) So essentially anything already inbuilt in WPF.
Thanks for any help :-D !!!
ListBox or ListView are good controls to use. If it's just the 'pretty' factor you don't like, you can provide Templates to change the appearance. But functionally, ListBox and ListView provide the function of that menu.
When working with WPF, that should be your primary motivation when choose controls. What FUNCTIONS the way you want. You can always make it LOOK different with Templates, but getting the right FUNCTION is the primary goal for the control.
I'm watching at this page:
http://leeontech.wordpress.com/2010/02/01/summary-row-in-datagrid/
But they're using silverlight. I'm trying to create that user control to use it in a WPF C# application. I mean, not using Silverlight. But I can't find the namespaces: GroupHeader
I'm having a hard time with this. Thanks in advance.
Okay listen, you can totally do this, and in some scenarios I even recommend it.
Using a CollectionViewSource you can easily group your data. In the HeaderTemplate you can even use an Expander (or make your own) and get the animation you might be wanting. Here's a link to a sample of this: http://jerrytech.blogspot.com/2010/06/wpf-data-presentation-step-by-step.html
Using an ItemsControl, you can easily present your groups and details. In the ItemTemplate you can use styles make this look like a grid (if that is really what you want). You can also shift the style based on the type if your collection has more than one type of object in it (eat that datagrid!).
You can wire up your column headers (which will really be custom objects, right?) and handle all the sorting and stuff like that. They will look just right! Not like datagrid WinForm column headers!
Here's what's hard (not impossible, but more coding).
User-resizable columns.
User-rearrangable columns.
New record using bottom, empty row.
Paste from Excel (doesn't work right in datagrid either).
Select Row, highlight Column header.
That's it.
In lots of situations, this is really nice.
For the most part, I cannot stand the datagrid. Too restricting on UX.
I don't think you're not going to be able to get a silverlight control working in WPF.
Adding a footer row to the WPF datagrid is something a lot of people have complained about; it's ridiculous that it wasn't included out of the box.
See this thread from MSDN
Having been through this myself, your best bet will probably be to bite the bullet and use a third party control. It sucks, I know.
I want my ListBox to have columns, and one of those columns have to be a clickable URL.
How can I achieve this?
You can't do it in a ListBox. You can create your own control, or settle for another existing one. Based on the question, I'd guess you're not yet at the stage where you're creating your own controls. That takes a pretty good understanding of existing controls and the way they work under the covers (but a google search for creating Winforms Controls should yield plenty of instructions.) Edit added It looks like te 4th and 5th links in combination on that google search should get you what you need. You can create your own user control and then do an array of them)
As far as for other possible alternatives, have you considered a DataGridView? A DataGridView can have a hyperlink and it can have checkbox columns, so this would be one possible alternative.
Here's a link for having a Hyperlink column in a DataGridView.
Well, it is possible by using the CustomTabOffsets property (unreliable) or the DrawItem event. And implementing the MouseDown event to find out if that particular 'column' was clicked.
But there's little point, a ListView control with View = Details gives you the same functionality.
How do I display a DataGridView within a cell of another datagridview in C# forms app?
How would I have to handle Sorting & value changed if this possible?
That is the only way I can display data to make some sense.. Think of it like I have a task column and dates column. Under the dates column I have a list of things to be done. These date columns are dynamic & there might be multiple date columns
That sounds like a difficult interface to use, have you considered some kind of tree control?
If you're determined to use data grid views, look at customizing data grid view columns and cells. You need to declare custom subclasses for the column and cell behaviour that you want. I don't know if it's possible to do what you want, but that's where I would start.
This is a suggestion since what your asking I do not think is possible with the built in DGV of .NET.
Using custom controls made by professional companies that provides a DataGrid with the capability of hierarchical data. For example a row can be expanded to show multiple entries (the multiple entries can be an entirely different table containing completely different columns even). Here are a few options that you can check out.
Infragistics WinGrid
Component One
There are a few other places/companies that make great .NET component packages that provide added features to the existing .NET components.
http://blogs.msdn.com/markrideout/archive/2006/01/08/510700.aspx
Found a link where hierarchichal datagrid is implemented.
Now, I have to either modify the control, or settle for hierarchichal gridview!
Hope this helps someone. Will update later
Currently, I'm in the process of making a custom solution for invoicing. I have created multiple ways for customers to create their template (HTML, Word, LaTex) and get invoices according to their template. However, these invoices are party manually generated.
So, the process is:
Request to create a new invoice
An preliminary invoice is created
The user gets a chance to make changes (i.e. add, remove, change rows)
Create a pdf
Just to be clear, the preliminary invoice does not need to be formatted as the template is, but you should be able to add/remove/change rows and for every cell, indicate whether the value should be visible in the final result.
My problem is that i cannot find a suitable way to display the preliminary invoices. I tried a datagrid (default, telerik, devexpress), but it's too messy. Besides a datagrid, i have no idea what i can use.
What controls can i use best to have a nice and usable UI.
Please don't be like this:
alt text http://bitsandpieces.us/wp-content/uploads/2008/03/imagesapple-20google-20and-20you.png
A typical UI paradigm for this kind of thing is to view it as two separate problems: giving the user a way of viewing the elements that he can modify, and giving him the ability to modify any specific element. You use a list control (ListBox, ListView, maybe TreeView if the elements are organized hierarchically or need to be grouped into categories) to present the elements, and then when the user selects an element the program presents a tabular presentation of field names and editable value controls.
Basically, you're dividing the program's functionality into two categories: stuff that the user wants to do to rows (add, remove, re-order, select) and stuff that the user wants to do to the selected row's elements.
You can mush these two sets of functionality into one if you use a DataGridView, but as you've seen that gets pretty ugly if there's any complexity to the elements you're editing.
Two possible approaches to this: the property-sheet paradigm (select object, right-click, select "Properties", edit values in a modal dialog), or a paradigm where the window's split into two panels, with one being the rows and the other being the details of the currently selected row. There are lots of others.
What is your platform? Winforms? WPF?
What exactly did you dislike about using a datagrid for this? Part of the problem is that whether you like it or not, you're going to be coding a datagrid - you essentially described features of one. If at all possible try to use someone else's datagrid because it will save you a lot of work. Typically, 3rd party datagrids should be fairly customizable, and you should be able to make it look however you want - and take advantage of the built in sorting, editing, grouping, etc. Creating a datagrid-like control from scratch isn't easy and should be avoided if possible.
You don't have to have a plain giant datagrid - you can crate a custom control that displays the invoice formatted however you like, with a live datagrid appearing only where the invoice shows tabular data, formatted to appear as an integral part of the invoice itself.
I'm doing something similar, where the client can edit or even remove the line items for the invoice prior to sending it to the client.
The current app they run their business on is a WebForms Intranet application, so this is an extension to that. So they can add/remove/edit rows fairly easily.
But Egor is right. You're essentially talking about a datagrid no matter what you do. I take it you want something 'cleaner' and more intuitive?
Simplicity is difficult.
I would take a look at what is already out there, especially for invoices, and see how they are doing it.
Not sure how big your company is, but it never hurts to take advantage of the large company applications and user interfaces, the pour thousands/millions of dollars into user interface design and testing.
I would take a look at any of the following (most offer a free trial, or just try searching for screenshots):
www.freshbooks.com
www.invoicera.com
www.getcashboard.com
www.simplifythis.com
Just some ideas ... hope this helps!