Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

DataGrid Appearance 1

Status
Not open for further replies.

Raenius

Programmer
Oct 14, 2003
77
0
0
NL
Hey all,

I'f done some searching but have not been able to find specifically what I am looking for so maybe some one here can help me..

If you look at my Datagrid here:


What I want is basically two things, I want to have the Router_name column automatically to expand so you can read the entire name and second I want to lose the grey bars on the left side of the data so that only just the data is displayed.

Can someone point me in the right direction?

Thanks in advance..

- Raenius

"Free will...is an illusion"
 
Oh and another question:

Whats wrong with the following:

Code:
SqlDataAdapter sa = new SqlDataAdapter("SELECT name AS Router_Name FROM ROUTER WHERE routerID IN (SELECT DISTINCT routerID FROM PINGS WHERE rtt>20)", myConnection);

Thanks!

- Raenius

"Free will...is an illusion"
 
To lose the gray bars:
Code:
dataGrid1.RowHeadersVisible = false;

If you want to auto-size the first column in the grid, you could run through the datasource and get the length of the longest value, then set the column to that size, e.g.
Code:
float max = 30; //minimum value

Graphics g = dataGrid1.CreateGraphics();

foreach (DataRow dr in ((DataTable)dataGrid1.DataSource).Rows)
{
	float w = g.MeasureString(dr[0].ToString(), dataGrid1.Font).Width;

	if (w > max) max = w;
}

dataGrid1.TableStyles[0].GridColumnStyles[0].Width = Convert.ToInt32(max);
Note that there may be much more efficient ways of doing this, on a large datasource this means looping through every row!
 
>
SqlDataAdapter sa = new SqlDataAdapter("SELECT name AS Router_Name FROM ROUTER WHERE routerID IN (SELECT DISTINCT routerID FROM PINGS WHERE rtt>20)", myConnection);
is a valid code like here.
string sTable = "Test_Router";
string sCon = "user id=...";
SqlConnection myConnection = new SqlConnection(sCon);
SqlDataAdapter myDataAdapter = new SqlDataAdapter();
myDataAdapter.SelectCommand = new SqlCommand("SELECT name AS Router_Name FROM ROUTER WHERE routerID IN (SELECT DISTINCT routerID FROM PINGS WHERE rtt>20)" , myConnection);
myConn.Open();
DataSet ds = new DataSet("DataSetName");
myDataAdapter.FillSchema(ds,SchemaType.Source,sTable);
myDataAdapter.Fill(ds,sTable);

2. Draw the text in a rectangle when the mouse is over the column and the text of this column is > the the size of the column.
-obislavu-
 
Thanks it works great except for the chaning of the columnwidth but that will work out in the end..

New questoin:

How can you add edit / delete buttons to display after each row of data?

- Raenius

"Free will...is an illusion"
 
Implement a custom DataGridColumn Style derived from DataGridColumnStyle and wrap there a Button object.
Lets name this class DataGridButtonColumn.
You can add the Edit/Delete columns to the DataGrid as follows:
Code:
DataGridTableStyle vStyle = new DataGridTableStyle();
vStyle.MappingName = "";
DataGridBoolColumn vColumnStyleEdit = new DataGridButtonColumn();
vColumnStyleEdit.AllowNull = false;
vColumnStyleEdit.HeaderText = "Edit";
vColumnStyleEdit.Alignment =  System.Windows.Forms.HorizontalAlignment.Center ; 
vColumnStyleEdit.Width = 60;
vStyle.GridColumnStyles.Add( vColumnStyleEdit );

//
DataGridBoolColumn vColumnStyleDel = new DataGridButtonColumn();
vColumnStyleDel.AllowNull = false;
vColumnStyleDel.HeaderText = "Delete";
vColumnStyleDel.Alignment =  System.Windows.Forms.HorizontalAlignment.Center ; 
vColumnStyleDel.Width = 60;
vStyle.GridColumnStyles.Add( vColumnStyleDel );
-obislavu-
 
Thanks again Obislavu, just to be on the safe side. Is there a way to implement this via Borland C# builder (windows) or does this HAVE to be hardcoded in...

In the meantime I will see if I can get this to work...

Thanks again...

- Raenius

"Free will...is an illusion"
 
Allright I have been toying with this and although for the clear help that Obislavu has given I don't seem to be able to get it to work.

This is how my Datagrid is initialised:

Code:
	private void WinForm3_Load(object sender, System.EventArgs e)
		{
			SqlConnection myConnection = new SqlConnection("user id=xxxxxxx;" +								   "password=xxxxx;server=x.x.x.x;" +
									   "Trusted_Connection=yes;" +
									   "database=xxxxx; " +
									   "connection timeout=30");

		try {
		SqlDataAdapter da = new SqlDataAdapter("SELECT name AS Router_Name FROM ROUTERS", myConnection);

		// create a new dataset
		DataSet ds = new DataSet();

		// fill dataset
		da.Fill(ds, "REMOVEROUTERS");
		// Attach DataSet to DataGrid
		//dataGrid1.DataSource = ds.DefaultViewManager;

		dataGrid1.DataSource = ds.Tables["REMOVEROUTERS"].DefaultView;

		// Close the Database connection
		myConnection.Close();
		}
		catch(Exception griderror)
		{
		myConnection.Close();
		MessageBox.Show(griderror.ToString(), "Error Message");
		}
		}
	}
}

This is how my DataGrid is built up:

Code:
			this.dataGrid1 = new System.Windows.Forms.DataGrid();
			((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
			this.SuspendLayout();
			// 
			// dataGrid1
			//
			this.dataGrid1.CaptionText = "Removable Routers";
			this.dataGrid1.DataMember = "";
			this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
			this.dataGrid1.Location = new System.Drawing.Point(32, 32);
			this.dataGrid1.Name = "dataGrid1";
			this.dataGrid1.Size = new System.Drawing.Size(272, 240);
			this.dataGrid1.TabIndex = 0;

This was all generated by Borland C# Builder and with some additional added programming ofcourse (many thanks to the people on this forum).

So what I want to do is add a delete button after each row that is displayed in the DataGrid. I have searched high and low for a way to do this in Borland itself but that appears to be impossible for some reason so I have to add the code myself. No problem if I can just find out what that code is ;-)

If I look at the code that Obislavu gave me I see that I have to build a class called DataGridButtonColumn with probably some methods in it. Currently I have no idea on how to proceed on this, I've searched on MSDN etc for a example of this but to no avail unfortunately.

Apparantly the line:
DataGridTableStyle vStyle = new DataGridTableStyle();
represents the table drawn by the System.Windows.Forms.DataGrid control at run time.

The line: vStyle.MappingName = ""; basically you give the name of the DataTable you use, as I use a DataSet I don't think this applies and it will remain blanc (or do I fill in the SQL Adapter name?)..

After that we get the reference to the class DataGridButtonColumn() with: DataGridBoolColumn vColumnStyleEdit = new DataGridButtonColumn();

This is the part I don't really understand, what will be in the class?

After this you get to define the column with the lines:

vColumnStyleEdit.AllowNull = false;
vColumnStyleEdit.HeaderText = "Edit";
vColumnStyleEdit.Alignment = System.Windows.Forms.HorizontalAlignment.Center ;
vColumnStyleEdit.Width = 60;

This speaks for itself, although no event handlers are present these must be defined here as well right?

Also where in the code must this all be placed, in the WinForm_Load correct?

Then you get the line:
vStyle.GridColumnStyles.Add( vColumnStyleEdit );
which I think will add the button to the GridColumnStyles but I do not see a reference to the DataGrid must this be made here?

You see a lot of questions and remarks, I hope someone can help me a bit further on this...(Obislavu?)

In any case thanks for the help already given and I hope to hear from someone soon...

Kind regards,

Raenius...

ps. Longest post ever! ;-)





"Free will...is an illusion"
 
There are only two kind of DataGridColumnStyle available (for now): DataGridBoolColumn and DataGridTextColumn.
If you want the grid to use another type of column like a Button, a ComboBox, a ListBox, a TreeView etc you should implement these by deriving from the DataGridColumnStyle and wraping a Button or a ComboBox or a ListBox.
This kind of grid is available from third party companies.
In a class such DataGridButtonColumn you should override events regarding the Button control, like OnClick, override some properties and all the code will be in this class (DataGridButtonColumn) and not in WinForm_Load()!.
>vStyle.GridColumnStyles.Add( vColumnStyleEdit );
Yes, you only add the column style to the TableStyle of the grid and the grid is built on that table.
>vStyle.MappingName = "";
Yes, you sholud provide a name there and it is the name of the DataTable.
I have not yet a complete code of the DataGridButtonColumn class.
-obislavu-
 
Thanks for the quick reply although the news was not that good... I am not able to buy a solution from third party companies for the implementation of such a class. So I will have to write it myself, strange that there are so many examples of how to use the buttons but not to make the buttons :(

Placing of the code was obvious, stupid on my part.

MappingName is a strange issue, how can I input a DataTable name as I am not using that to my knowledge...

- Raenius


"Free will...is an illusion"
 
I've given up on the delete button inside the Grid. I just have circumvented it by adding a single delete button on the form and deleting the currently selected row by implementing the following:

Code:
	private void RemoveRouterDelete_button_Click(object sender, System.EventArgs e)
		{
			System.Windows.Forms.DataGridCell selectedCell = dataGrid1.CurrentCell;
			object selectedItem = dataGrid1[selectedCell.RowNumber, selectedCell.ColumnNumber];
			string routername = Convert.ToString(selectedItem);
			DialogResult result;
			result = MessageBox.Show("Are you sure you want to delete this router: "+routername+"?","Delete Router...",MessageBoxButtons.OKCancel,MessageBoxIcon.Warning);
			if(result == DialogResult.OK)
			{

				try
				{

				 bool yes = DeleteRouter(routername);

				 if (yes ==true)
				 {
				 MessageBox.Show("Succes!");
				 }
				 else
				 {
				 MessageBox.Show("Failure!");
				 }
				 // Call function which:
				 // Connects to database
				 // Updates database
				 // Updates data source
				 // Refreshes data source
				 // Refreshes Form
				}
				catch (Exception rmerror)
				{
				MessageBox.Show(rmerror.ToString(), "Error Message");
				}
			}
			else
			{
			}
		}

		private bool DeleteRouter(string routername)
		{
		//MessageBox.Show(routername);
		bool result = false;

		SqlConnection myConnection = new SqlConnection("user id=xxxxx;" +
									   "password=xxxxx;server=xxxxx;" +
									   "Trusted_Connection=yes;" +
									   "database=xxxxxx; " +
									   "connection timeout=30");
		SqlCommand myDeleteCommand= new SqlCommand("DELETE FROM ROUTERS WHERE name="+routername.ToString()+"", myConnection);
		try
		{
		myConnection.Open();

		// try to execute delete command

		MessageBox.Show("Attempting Deletion");
		myDeleteCommand.ExecuteNonQuery();

		MessageBox.Show("Succesfully completed SQL Query");
		result = true;

		// Database was succesfully updated, close connection
		myConnection.Close();

		// Refresh form

		this.Refresh();

		}
		catch(Exception delerror)
		{
		 myConnection.Close();
		 MessageBox.Show(delerror.ToString(), "Error Message");
		}
		
		return result;
		}

Only problem is the SQL statement is gives me back that inside routername there are invalid columns, weird as I am using a WHERE clause :(

- Raenius

"Free will...is an illusion"
 
Nevermind the last question it all worked out in the end, I've started using parameterised queries which work pretty well and maybe even some performance gain..

Now I'm stuck at a insert of multiple fields into multiple tables with one primary key (which is autogenerated) which needs to be added as a foreign key in different databases...I'm currently doing the hard way: Insert in one table, retreiving MAX (ID) and using that to input in other tables....

Code:
SqlCommand SelectCommand= new SqlCommand("SELECT MAX(routerID) FROM ROUTERS", myConnection);
					SqlDataReader reader = SelectCommand.ExecuteReader();

						while (true)
						{
							if (reader.Read())
							{
								string id = reader["routerID"].ToString();
								MessageBox.Show(id.ToString());
							}
							else
							{
								reader.NextResult();
							}
						}

Problem is its giving me a system.indexoutofrange error...

Any suggestions?

- Raenius

"Free will...is an illusion"
 
I am still having problems with the resizing of the column width according to the size of the largest field.

On my winform_load the datagrid is initialised and displayed using the following code:
Code:
try {

		SqlDataAdapter da = new SqlDataAdapter("SELECT name AS Router_Name FROM ROUTERS", myConnection);

		DataSet ds = new DataSet();

		da.Fill(ds, "EDITABLEROUTERS");
		dataGrid1.DataSource = ds.Tables["EDITABLEROUTERS"].DefaultView;

		myConnection.Close();
		}
		catch(Exception ederror)
		{
		myConnection.Close();
		MessageBox.Show(ederror.ToString(), "Error Message");
		}

Can anyone shed some light on this? I know ?I have to loop through the datasource and find the longest character value but I have not a good idea on how to implement this.

Thanks in advance...

- Raenius

"Free will...is an illusion"
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top