Friday, August 18, 2006

Getting parent

I have a control embedded in another nested control.

I need to get a parent several levels up (but not all the way up), basically I need to do a recursive search up the parents until I hit a parent that is one of two types - then I want to know which of the two types it was.

I haven't figured out how to do this: it seems that the Parent property of Control is unreliable - sometimes it sets itself, othertimes it is null. I am using ContainerControls so I tried the ParentForm property but this jumps me up all the way to my application form (further up the ancestory tree than I want to go). There is also Form.Owner but my control is not a form.

Right now, I am just manually setting my own propetry as I create each control ( I have to do this for a few different controls along the ancestory line)

Thursday, August 10, 2006

DataGridView - don't highlight selection

If you don't want to highlight the selected row in your DataGridView - maybe the whole grid is read only and you don't want users to be able to highlight a row because you don't do anything special with the highlighted row - here's how to do it:

go to your defaultCellStyle under your DataGridView properties.

Set SelectionBackColor to white (or same color as non-selected rows)

Voila!

Tuesday, August 01, 2006

Error connecting to database

Are you getting this error?

Sqlcmd: Error: Microsoft SQL Native Client: An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections.

The default solution is here:

http://support.microsoft.com/?kbid=914277&SD=tech

But what if this doesn't work? Or you're not using SQL Server 2005? Or you don't have access to the database and want to try a local solution first?

First:

Disable Simple File Sharing on your computer:
http://compnetworking.about.com/cs/winxpnetworking/ht/winxpsfs.htm

If that doesn't work, try adding the port number to your connection string. For example, change:

servername

to:

servername,1234

also, if you are connecting to a local database try changing the data source in your connection string from:

(local)

to

.\SQLEXPRESS

(This may be true even if you are not using SQLEXPRESS but have it installed on your machine, or used it at one point)

Hope this helps!

Monday, July 17, 2006

.Net Cloning

Two interesting articles on cloning:

http://www.codeproject.com/csharp/cloneimpl_class.asp?forumid=13965&exp=0&select=377851&df=100&fr=21.5#xx377851xx

http://www.agiledeveloper.com/articles/cloning072002.htm

The first one uses Reflection - main advantage is you don't have to update the function if you add fields to t he class - main disadvantage is you don't have detailed control (e.g. - if a field supports ICloneable it uses the clone mehtod, but Clone does a shallow copy - what if you want to do a deep copy - or what if you want to do some custom action - like generate a new guid for a guid field? - you can add customizations but then the function is not generic and you lose the main advantage.

The main disadvantge of the second one is that you have to modify it with any changes to the fields - but it is elegant and simple and for hte problem I'm working on right now, I have a lot of custom handling for different fields, so I don't think the first one would work.

Serialization is another option, but this gives a security issue - also may be a performance issue? and I would still have to write additional code for my custom handling.

Saturday, July 15, 2006

DataGridViewButtonColumn click event

I just realized that you capture the click event for the DataGridViewButtonColumn the same way you do any other column - through the DataGridView's CellClick event - The button column does not have it's own click event! So basically what makes it a button column is not it's functionality but the picture of the button that gets drawn and the press/depress "animation." In fact none of the column types expose their own events - they all rely on capturing the DataGridViews events.

More on DataPropertyName

If a DataGridViewColumn has a null DataPropertyName the columns index will be set to 0. (if there is more than 1 column like this, then 0,1,2, etc.) - this of course messes up the indexes of your other columns too.

So if you are capturing the cellclick event and you find that e.ColumnIndex is not what you expect, it may be that you forgot to bind one of your columns (not necessarily the same one you're clicking) to a DataColumn. This is particularly likely if one of your columns if a DataGridViewButtoncolumn, or some other column that has no data behind it - so you may not have noticed it wasn't bound.

This is the same problem I was running into with the DataGridViewImageColumn - but with this problem I have no workaround becuase it seems that binding the column properly causes the image not to show up - I'll have to make a test app to confirm this.

DataPropertyName

Looking back over my old posts it seems that for the DataGridViewImageColumn, setting the DataPropertyName to the same name as the corresponding column in the DataTable causing a problem, but with the DataGridViewTextBoxColumn, you must set the DataPropertyName to the name of the corresponding DataColumn. Hmm...

DataGridViewColumn DataPropertyName

This is an important property in every DataGridViewColumn. If you are binding to a DataTable, you must set this property to the name of the column in the DataTable that you want to bind this DataGridColumn to.

For example: Open a new Windows Form project. Add a DataGridView control to the main form. Right click on the DataGridView, select edit columns, add a DataGridViewTextBoxColumn (just call it Column1).

Now put this code in the constructor:


public partial class Form1 : Form
{
private DataTable dt;
private DataSet ds;

public Form1()
{
InitializeComponent();
dt = new DataTable("mytable");
dt.Columns.Add("Name");
dt.Rows.Add(new object[]{"michelle"});
ds = new DataSet();
ds.Tables.Add(dt);
this.dataGridView1.DataSource = ds;
this.dataGridView1.DataMember = "mytable";
}
}

Run the project - two columns will show up - Column1 and Name, the one row, will be blank for Column1 and Michelle for Name. This is probably not what we want.

Now go back to the Designer View - right click on the DataGridView and select edit columns, select Column1 and set DataPropertyName to Name.

Now run it again. This time you should get one column titled Name, with one row, michelle. Much better!

Sunday, July 09, 2006

To Change current cell in DataGridView..

this.myDGV.CurrentCell = this.myDGV.Rows[0].Cells[1];

This will automatically highlight the row as well - at least if you have MultiSelect set to false and SelectionMode to FullRowSelect

Saturday, July 08, 2006

Highlight entire row in DataGridView

To highlight an entire row in the DataGridView, set the SelectionMode property to FullRowSelect.

DataGridViewImageColumn

The first problem I haad with this column type is that my image wasn't showing up - I could see the image just fine in the column editor in Design View, but when I ran my app, only a blank image (red x) showed up.

The problem turned out to be with the DataTable I was binding to. Although the DataTable did have columns corresponding to my two image columns, those columns didn't have any data. Populating them with blank strings in every row fixed the problem...

...and uncovered a bigger problem. Now I was getting a whole slew of these exceptions whenever my DataGridView was first painted:
Invalid cast from System.String to System.Drawing.Image

The problem turned out to be with the names of the DataColumns in my DataTable - the two columns corresponding to my Image Columns were called "Up" and "Down" - e.g.:


this.myDataTable.Columns.AddRange(
new DataColumn[]{
new DataColumn("Description", typeof(string)),
new DataColumn("Up", typeof(string)),
new DataColumn("Down", typeof(string)),
new DataColumn("Delete", typeof(string))});

I'm still not sure why "Up" and "Down" caused a problem - these names happened to be the same as the DataPropertyName for the corresponding DataGridViewImageColumns, so that may have been the problem. Changing these two column names to blank strings or to "1" and "2" solved the problem.

..But now I had a new problem..it seems that when you add a DataGridViewImageColumn, another blank column is automatically added next to the DataGridView. So in this case I was getting two extra columns showing up. The only way I've found around this so far is to figure out the indexes of the extra columns and set their visible property to false.

After all that, I had a nice data grid with my image columns showing up and without any exceptions or extra columns!

DataGridViewButtonColumn

I've just started experimenting with the new DataGridView control in 2.0. I've learned a couple interesting things so far while trying to create some button columns.

First, in order to display text on the DataGridViewButtonColumn you must not only set the Text property, but must also set the UseColumnTextForButtonValue to true.

You cannot load an image on to a DataGridViewButtonColumn. Instead you must use a DataGridViewImageControl and capture the cellclick event to treat it like a button.

First Post

Welcome to Everything Dot Net. The purpose of this blog is to discuss anything and everything related to Microsoft.Net.