|
-
Sep 25th, 2007, 09:37 AM
#1
Thread Starter
Frenzied Member
[2.0] Repeating, Databound Form Control Needed
I have a Form on which I need to show repeating rows of data bound to a database. I can't use a datagrid because I have several rows of textboxes, with buttons, checkboxes, dropdowns, and labels associated with each row.
(If you're familiar with Microsoft Access, it's simple to design a form template for a row and you can set the controls to repeat in any layout style)
My only thought was to use the TableLayoutPanel control and create the other controls and set their values at runtime, adding a row to the panel for each record.
Is there a better way to do this?
[Edit]
I'm using 2.0 so I meant DataGridView, not DataGrid.
Last edited by wey97; Sep 26th, 2007 at 08:04 AM.
-
Sep 26th, 2007, 02:48 AM
#2
Re: [2.0] Repeating, Databound Form Control Needed
The DataGridView allows you to embed basically any control you like in a cell, so you could use one of those. That said, the DataGrid can do this too but it's much more painful to implement.
If you don't just want straight rows as you get in a grid then you could check out the DataRepeater class in the QSS WFC library from the link in my signature.
-
Sep 26th, 2007, 08:08 AM
#3
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
 Originally Posted by jmcilhinney
The DataGridView allows you to embed basically any control you like in a cell, so you could use one of those. That said, the DataGrid can do this too but it's much more painful to implement.
If you don't just want straight rows as you get in a grid then you could check out the DataRepeater class in the QSS WFC library from the link in my signature.
I meant DataGridView not DataGrid since I'm in 2.0. The rows have straight borders, there are just several rows of controls in each row that repeats, so it's going to be a serious pain adding and positioning them dynamically.
I have about 38 controls for each row, and they don't all have definite column boundaries, unless I can "merge" cells.
Maybe I could create a user control as my template and add the user control to the DataGridView.
Last edited by wey97; Sep 26th, 2007 at 08:12 AM.
-
Sep 26th, 2007, 08:45 AM
#4
Re: [2.0] Repeating, Databound Form Control Needed
Did you check out the QSS DataRepeater? It basically allows you to create multiple instances of a UserControl of any configuration for multiple records.
-
Sep 26th, 2007, 08:47 AM
#5
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
 Originally Posted by jmcilhinney
Did you check out the QSS DataRepeater? It basically allows you to create multiple instances of a UserControl of any configuration for multiple records.
I did. It looks rather awesome. Just depends if my client will allow me to use a 3rd party control or not. They can be picky at times
-
Sep 26th, 2007, 05:04 PM
#6
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
Apparently I can't use third party controls 
So far I have MyUserControl inheriting from UserControl.
I have MyDataGridViewColumn inheriting from DataGridViewColumn and MyDataGridViewCell inheriting from DataGridViewCell.
What I don't know is what method to override in MyDataGridViewCell to output or render MyUserControl to the DataGridView.
-
Sep 26th, 2007, 06:05 PM
#7
Re: [2.0] Repeating, Databound Form Control Needed
You also have to inherit your UserControl and implement the IDataGridViewEditingControl interface. Here's an MSDN example for the DateTiePicker control.
-
Sep 27th, 2007, 03:45 PM
#8
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
 Originally Posted by jmcilhinney
You also have to inherit your UserControl and implement the IDataGridViewEditingControl interface. Here's an MSDN example for the DateTiePicker control.
Right, I had found this but wasn't sure if that would be the best way to do what I wanted since MyUserControl had multiple control instances instead of just one control like the DateTimePicker. I couldn't see how I could use the properties like EditingControlFormattedValue and other "value" type properties implemented by the IDataGridViewEditingControl interface. What I did for the time being is just let that refer to the primary key for the row.
Now, when the grid is displayed, obviously only the primary key value is shown in the DataGridViewCell until I double click the cell and editing begins. The user control is displayed and I see my multiple buttons, textboxes, labels, etc.
The only problem with that is I'd like to see all of the controls, all the time, not just when a row is being edited.
-
Sep 27th, 2007, 06:05 PM
#9
Re: [2.0] Repeating, Databound Form Control Needed
Here's how a DataGridView works. When it is first displayed it contains no controls at all. Each cell is basically a rendered image of the cell contents. When you start editing a cell a control of the appropriate type is created, embedded in the cell and that's where you edit the data. When you end the editing session the appropriate value is pushed from the control to the underlying cell and the control is removed. That means that you now see the rendered image of the cell again. If you then start editing another cell, if the required control is of the same type then the same control will be used to edit the new cell, thus saving the time and resources it would take to create a new control.
The upshot of all this is that if you want to see all your controls in a cell when you're not editing then you have to implement your cell class to render an image of your control.
-
Oct 1st, 2007, 09:24 AM
#10
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
 Originally Posted by jmcilhinney
Here's how a DataGridView works. When it is first displayed it contains no controls at all. Each cell is basically a rendered image of the cell contents. When you start editing a cell a control of the appropriate type is created, embedded in the cell and that's where you edit the data. When you end the editing session the appropriate value is pushed from the control to the underlying cell and the control is removed. That means that you now see the rendered image of the cell again. If you then start editing another cell, if the required control is of the same type then the same control will be used to edit the new cell, thus saving the time and resources it would take to create a new control.
The upshot of all this is that if you want to see all your controls in a cell when you're not editing then you have to implement your cell class to render an image of your control.
I inherited the cell class from DataGridViewTextBoxCell just to get things to work correctly. I tried to inherit my cell from DataGridViewCell but couldn't get the user control to show, I'm guessing because I didn't override or handle the proper methods.
Which should I inherit from and what do I override/handle to show the user control when not in edit mode?
-
Oct 1st, 2007, 06:05 PM
#11
Re: [2.0] Repeating, Databound Form Control Needed
If you don't want to use the functionality of the DataGridViewTextBoxCell class then you should not inherit it. I suggest that you read the documentation for the DataGridViewCell class. It will tell you what each member is for. Just note that you will NOT be showing your UserControl in the cells when not in edit mode. The idea is that you draw an appropriate representation of your control, which may or may be exactly as it actually looks, using GDI+. It's the fact that the grid doesn't ever actually contain more than one embedded control that prevents it grinding to a halt. You need to read to learn. Go to MSDN and read about the DGV control.
-
Oct 2nd, 2007, 01:57 PM
#12
Thread Starter
Frenzied Member
Re: [2.0] Repeating, Databound Form Control Needed
 Originally Posted by jmcilhinney
If you don't want to use the functionality of the DataGridViewTextBoxCell class then you should not inherit it. I suggest that you read the documentation for the DataGridViewCell class. It will tell you what each member is for. Just note that you will NOT be showing your UserControl in the cells when not in edit mode. The idea is that you draw an appropriate representation of your control, which may or may be exactly as it actually looks, using GDI+. It's the fact that the grid doesn't ever actually contain more than one embedded control that prevents it grinding to a halt. You need to read to learn. Go to MSDN and read about the DGV control.
I had read as you suggested. All of the code and examples I found inheriting from DataGridViewCell all override the OnPaint method.
So if I have to paint it here goes:
c sharp Code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Drawing;
using WindowsControlLibrary1;
namespace WindowsApplication1
{
public class MyDataGridViewCell :
//System.Windows.Forms.DataGridViewTextBoxCell
System.Windows.Forms.DataGridViewCell
{
public MyDataGridViewCell(): base(){}
public override Type FormattedValueType
{
get{ return typeof(MyUserControl); }
}
public MyUserControl MyControl
{
get { return this.DataGridView.EditingControl as MyUserControl; }
}
public override Type EditType
{
get{ return typeof(MyUserControl); }
}
protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, System.ComponentModel.TypeConverter valueTypeConverter, System.ComponentModel.TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
{
value = MyControl;
return value;
}
protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
SolidBrush cellBackground = new SolidBrush(cellStyle.BackColor);
graphics.FillRectangle(cellBackground, cellBounds);
cellBackground.Dispose();
if (MyControl != null)
{
foreach (Control c in MyControl.Controls)
{
Rectangle rt = cellBounds;
rt.X += c.Location.X;
rt.Y += c.Location.Y;
rt.Width = c.Width;
rt.Height = c.Height;
if (c is TextBox)
TextBoxRenderer.DrawTextBox(graphics, rt, c.Text, c.Font, TextBoxState.Normal);
if (c is Button)
ButtonRenderer.DrawButton(graphics, rt, c.Text, c.Font, false, PushButtonState.Normal);
if (c is Label)
TextRenderer.DrawText(graphics, c.Text, c.Font, rt.Location, c.ForeColor);
}
}
base.Paint(graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
}
public override Type ValueType
{
get { return typeof(MyUserControl); }
}
}
}
This won't fit my needs because I want to display the exact values of all the user controls at all times like the QSS DataRepeater control you suggested.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|