Search code examples
c#winformsobjectlistview

ObjectListView editing doesn't work


I'm trying to create a simple listbox with ObjectListView (WinForm, C#). The goal is to have a single value (a double) and a check box.

I want to be able to edit the double value by Single Click, so here are the relevant lines of code from my MyWindow.Designer.cs file (i've left out the default values for efficiency):

this.olvDepths = new BrightIdeasSoftware.ObjectListView();
this.olvColumn1 = ((BrightIdeasSoftware.OLVColumn)(new BrightIdeasSoftware.OLVColumn()));

...

this.olvDepths.CellEditActivation = BrightIdeasSoftware.ObjectListView.CellEditActivateMode.SingleClick;
this.olvDepths.CheckBoxes = true;
this.olvDepths.CheckedAspectName = "IsDefault";
this.olvDepths.FullRowSelect = true;

// 
// olvColumn1
// 
this.olvColumn1.AspectName = "Depth";
this.olvColumn1.Text = "";
this.olvColumn1.IsEditable = true;

I then create a list of my class (ShieldingEntry) and use the olvDepths.SetObjects() with the list. My ShieldingEntry class looks like this:

public class ShieldingEntry
{
    public double Depth { get; set; }
    public bool IsDefault { get; set; }
}

However, when I click the field, it doesn't go into edit mode. I've also tried the DoubleClick, SingleClickAlways, and F2Only modes and they don't work either.

The Checkbox works fine.

************** I have additional information *********************

I've pulled and build the ObjectListView source, so I could step through it.

I put a breakpoint in the OLV StartCellEdit method and it gets called and appears to setup and select the control appropriately. It just never appears...

As I noted in the comments on the answer below, I've got this control on a tabbed dialog, and if I switch to another tab, then back, the control works fine.

What am I missing?


Solution

  • I've used ObjectListView before, and here is what I had to do:

    Handle the CellEditStarting event. This event is raised when the cell goes into edit mode. Since OLV doesn't really have built-in editors, you have to make your own. Then handle the CellEditFinishing event to validate the data before putting it back into your model.

    So first, handling the CellEditStarting event:

        private void objlv_CellEditStarting(object sender, CellEditEventArgs e)
        {
            //e.Column.AspectName gives the model column name of the editing column
    
            if (e.Column.AspectName == "DoubleValue")
            {
                NumericUpDown nud = new NumericUpDown();
                nud.MinValue = 0.0;
                nud.MaxValue = 1000.0;
                nud.Value = (double)e.Value;
                e.Control = nud;
            }
        }
    

    This creates your editing control. If you want to make sure the size is right, you can set the size of the control (in this case a NumericUpDown) to the cell bounds using e.CellBounds from the event object.

    This will show the editor when you click in the cell. Then you can handle the editor finished event to validate the data:

        private void objlv_CellEditFinishing(object sender, CellEditEventArgs e)
        {
            if (e.Column.AspectName == "DoubleValue")
            {
                //Here you can verify data, if the data is wrong, call
                if ((double)e.NewValue > 10000.0)
                    e.Cancel = true;
            }
        }
    

    I don't think handling it is required, but its good practice to validate data from the user.

    The editing control in the CellEditStarting event can be any control, even a user defined one. I've used a lot of user defined controls (like textboxes with browse buttons) in the cell editor.

    [Edit]

    I uploaded an example here dropbox link that seems to work. Might not be in the exact view as needed, but seems to do the job.