C#

Moderators: None (Apply to moderate this forum)
Number of threads: 2722
Number of posts: 5749

This Forum Only
Post New Thread
Single Post View       Linear View       Threaded View      f

Report
DataGridView problem Posted by esb1922 on 25 Apr 2009 at 8:20 AM
I have DataGridView control with 2 editable columns. 1 of them (column 1) should accept only digits and decimal point, another (column 2) only digits.

void dGr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (dGr.CurrentCell.ColumnIndex == 1)
{
if (e.Control is TextBox)
{
TextBox tb = e.Control as TextBox;
tb.KeyPress += new KeyPressEventHandler(tb_KeyPress);
}
}
else if (dGr.CurrentCell.ColumnIndex == 2)
{
if (e.Control is TextBox)
{
TextBox tb = e.Control as TextBox;
tb.KeyPress += new KeyPressEventHandler(tb_KeyPress2);
}
}
}

void tb_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(char.IsDigit(e.KeyChar)))
{
if (e.KeyChar != '\b' && e.KeyChar != '.') //allow the backspace key and decimal point
e.Handled = true;
}
}

void tb_KeyPress2(object sender, KeyPressEventArgs e)
{
if (!(char.IsDigit(e.KeyChar)))
{
if (e.KeyChar != '\b')
e.Handled = true;
}
}

The problem: at the beginning column 1 accepts only digits and decimal point as intended, but after I try to edit column 2 cells, column 1 stops taking a decimal point and behaves exactly like column 2. Any idea why it happens?


Also -
I'd like to change a column's background color to yellow.

dGr.Columns["MyColumn"].DefaultCellStyle.BackColor = Color.LightYellow;

That statement will not change the alternating rows DefaultCellStyle. So I have only half of all rows with yellow background. How to fix that?






Report
Re: DataGridView problem Posted by Psightoplazm on 25 Apr 2009 at 8:54 AM
The reason why it seems your event handler for one column is bleeding over into the other column is because the actual "textbox" used for editing in the datagrid view is recycled. You are actually adding more and more handlers to it every time it is shown according to this code.

so after 3 edits to column 1, the column 1 handler is called 3 times every key press.

after an edit to column 2, the column 1 handler is called 3 times and the column 2 handler is called 1 time per every key press.

What you might do is assign the handler somewhere else - or only once to the textbox and inside the handler itself grab what the active column is and perform your logic there.


as for the other part to your question - to override just a single columns behavior you can tap into the paint events of the cells and override the formatting manually.

></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by esb1922 on 25 Apr 2009 at 9:04 AM
Yes thanks, I figured it out that the CellFormatting event does the trick:
if (dGr.Columns[e.ColumnIndex].Name == "MyColumn")
e.CellStyle.BackColor = Color.Yellow;

But I'm not sure I understood how to fix the first problem.
Can you elaborate please how to assign handler somewhere else?
Report
Re: DataGridView problem Posted by Psightoplazm on 25 Apr 2009 at 9:09 AM
what I meant by assign the handler somewhere else was to use a different event but I would really recomend just inheriting the column and cells into your own classes so you can just access the protected functionality directly and make it function however you want.

This way you can even add a property onto the column that can turn on or off decimal points. It's an extra couple of files in your project, but I assure you that your code will be alot happier.

also as a side note: you can use -= on an event handler to remove it from the firing queue - so whenever the textbox is hidden for example.

></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by Psightoplazm on 25 Apr 2009 at 9:05 AM
Also - I think at some point you may just want to inherit the datagridviewtextcolumn and cells into your own classes so you can override functionality or add your own custom functionality all together and not have to rely on event handlers so much.

></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by esb1922 on 25 Apr 2009 at 9:29 AM
thanks, I'll definitely try that later. Meanwhile I got a quick fix (from other forum)
Changed
if (e.KeyChar != '\b' && e.KeyChar != '.')
e.Handled = true;

To
if (e.KeyChar != '\b' && e.KeyChar != '.')
e.Handled = true;
else
e.Handled = false

Apparently e.Handled doesn't have default but remembers its previous value.


Report
Re: DataGridView problem Posted by esb1922 on 27 Apr 2009 at 8:29 AM
One more DataGridView question

I add a check box column, and when I sort the DataGridView by clicking columns' headers it resets check box column values. Why does it happen and is there any way to preserve the values while sorting?
Report
Re: DataGridView problem Posted by Psightoplazm on 27 Apr 2009 at 11:12 AM
So short of seeing your application to figure out the problem (which I would rather not do, sorry) I would say if you are using a binding source or something, you might need to commit changes prior to a sort.

Also: while it appears someone offered you a hack to fix your original problem, there is still a much more serious issue going on there.

If you keep adding handlers to an event on an object (+= MyHandler...), every edit you make is going to slowly degrade your application's performance little by little.

let's say one of your users has made 1000 edits - now for every single number they type into those fields, your handlers are being called 1000 times per event!

At the very least - even though it's messy - you should be using a '-=' on the text box's event to remove the handler after the edit has been made.

Just so you can see what is going on, try this:

void dGr_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    if (dGr.CurrentCell.ColumnIndex == 1)
    {
        if (e.Control is TextBox)
        {
            TextBox tb = e.Control as TextBox;
            tb.KeyPress += delegate { MessageBox.Show("Handler Fired!"); };
        }
    }
}



Now make about 3 different edits in the column with an index of 1 -

On your first edit: a message box will pop up once per key press.
On your second edit: A message box will pop up twice per key press.
on your third edit: A message box will pop up three times per key press.
and so on...

The reason why the hack you were given works is because the last handler that has been added just happens to be the right one for the column you are editing and is therefore the last one called and the last one to set your event arg values. The reason your event args seem to be retaining values between calls is because each call that is being made per event is sharing the same eventarg object and each one is setting values on it.

></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by esb1922 on 27 Apr 2009 at 11:33 AM
Psightoplasm

You are right I told previously that I'll definitely try later what you are suggesting...

As for the check box column it's unbound and is the reason it gets unchecked on sorting (there is no source for that), so I'm not sure how to preserve checked values
Report
Re: DataGridView problem Posted by Psightoplazm on 27 Apr 2009 at 1:36 PM
I asked one of my co-workers and it sounds like if the checkbox column is not bound to anything then this will happen just as in issue with the datagridview - is there a reason you can't create a BindingList or something you can bind it to in order to retain the values?

></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by esb1922 on 27 Apr 2009 at 2:55 PM
well, I add a checkbox column in order not to modify the database immediately. Just to check multiple roows and then click Update, Delete, or Reset buttons. I could probably create a bindinglist... or if I knew what events are fired on column's header click before and after sorting...

Report
Re: DataGridView problem Posted by esb1922 on 28 Apr 2009 at 5:43 AM
I tried to use BindingList but all cells are not editable now even if I set MyBindingList.AllowEdit to true. No sure what the difference is.

Of course, it'd be easier instead of adding checkbox column, add true/false field in the database SELECT statement, but I use SQLIte which doesn't support boolean type.

Here is my pretty basic code:

private class Card
{
private String _card;
private String _image, _note;
private bool _check;

public Card(String card, String image, String note, bool check)
{
_card = card;
_image = image;
_note = note;
_check = check;
}

public String card { get { return _card; } }
public String image { get { return _image; } }
public String note { get { return _note; } }
public bool check { get { return _check; } }
}

private BindingList<Card> CardList;

and then after I get Dataset (ds)

CardList = new BindingList<Card>();
CardList.AllowEdit = true;

for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
CardList.Add(new Card(ds.Tables[0].Rows[i].ItemArray[0].ToString(), ds.Tables[0].Rows[i].ItemArray[1].ToString(),
ds.Tables[0].Rows[i].ItemArray[2].ToString(), false));
}

dGrCards.DataSource = CardList;

Report
Re: DataGridView problem Posted by Psightoplazm on 28 Apr 2009 at 7:54 AM
I think the problem is that your card class has only getters and not setters on the properties. This is why you can't edit them.

you might also try doing this on the Check property (since you can't use boolean):

public class Card
{
    public Card(string name, string image, string message, int check)
    {
        Card = name;
        Image = image;
        Note = message;
        _check = check;
    }

    public string Card { get; set; }
    public string Image { get; set; }
    public string Note { get; set; }

    // wrap your int value with a boolean property
    private int _check;
    public bool Check
    {
        get { return (_check > 0); }
        set { _check = value ? 1 : 0; }
    }

    // for saving to the db later
    public int GetCheckValue()
    {
        return _check;
    }
}


></\/~Psightoplasm`~
Report
Re: DataGridView problem Posted by esb1922 on 28 Apr 2009 at 9:04 AM
Yes, setters... but now columns are not sortable (headers click doesn't do anything)
Report
Re: DataGridView problem Posted by esb1922 on 28 Apr 2009 at 9:54 AM
I added Sortable BindingList inherited from BindingList. It's sorting the check box column fine but the feature I mentioned before (when datagridview is sorted automatically on the cell value edit) is lost. I probably can leave with that for now.

Psightoplazm, thanks a lot for your time
Report
Re: DataGridView problem Posted by Psightoplazm on 28 Apr 2009 at 11:12 AM
hehe - kk - sorry there isn't a better solution for you - perhaps another poster will be of more help.
Report
Re: DataGridView problem Posted by esb1922 on 28 Apr 2009 at 11:46 AM
Actually I could accomplish the same without using BindingList.
I could just to check what was hit on MouseDown event and if it was a ColumnHeader, then remember all unique column values and corresponding check boxes, and then on Sorted event, restore them...but then I'd have the problem I mentioned in the previous posts.
Report
Re: DataGridView problem Posted by esb1922 on 28 Apr 2009 at 3:06 PM
OMG Psightoplasm, what were we thinking. The solution has been in front of my eyes all the time.

Instead of adding checkbox column or using BindingList, I just needed to add a boolean field to the dataset

DataSet ds = //the database call

DataColumn col = new DataColumn();
col.ColumnName = "Check";
co.DataType = System.Type.GetType("System.Boolean");
col.DefaultValue = false;
ds.Tables[0].Columns.Add(col);

and the checkbox column becomes bound after

dataGridView.DataSource = ds.Tables[0];

Report
Re: DataGridView problem Posted by Psightoplazm on 28 Apr 2009 at 11:12 AM
--- removing double post
Report
Re: DataGridView problem Posted by surewiners on 25 Apr 2009 at 10:03 AM
if you want to know more
Please click http://www.nowgoal.com/23.shtml



 

Recent Jobs

Official Programmer's Heaven Blogs
Web Hosting | Browser and Social Games | Gadgets

Popular resources on Programmersheaven.com
Assembly | Basic | C | C# | C++ | Delphi | Flash | Java | JavaScript | Pascal | Perl | PHP | Python | Ruby | Visual Basic
© Copyright 2011 Programmersheaven.com - All rights reserved.
Reproduction in whole or in part, in any form or medium without express written permission is prohibited.
Violators of this policy may be subject to legal action. Please read our Terms Of Use and Privacy Statement for more information.
Operated by CommunityHeaven, a BootstrapLabs company.