show changes in Listview?

C

Co

Hi All,

I have a Listview with filenames. When I click the edit menu the form
to edit data is opened.
When I change the file and close the form I want to rebuild the
listview holding the data so the changes are seen
at once, my code doesn't do that:

Private Sub CMenuClick(ByVal sender As Object, ByVal e As
System.Windows.Forms.ToolStripItemClickedEventArgs)

Dim MyForm As New frmEdit
'Point to menu item clicked
Select Case e.ClickedItem.Text
Case "Open" : System.Diagnostics.Process.Start
(sDocumentName)
Case "Edit"
Dim I As Integer
For I = 0 To ListView.SelectedItems.Count - 1
MyForm.MyPropertyMydata = ListView.SelectedItems
(I).Tag
Next
MyForm.Show()
'now we have to clear and rebuild the items in the
Listview
Dim node = TreeView.SelectedNode
Dim nodeID = node.row("ID")
LoadListView(nodeID)
Case "Delete" : MsgBox("Delete")
End Select

End Sub

Regards
Marco
The Netherlands
 
J

joecool1969

Hi All,

I have a Listview with filenames. When I click the edit menu the form
to edit data is opened.
When I change the file and close the form I want to rebuild the
listview holding the data so the changes are seen
at once, my code doesn't do that:

Private Sub CMenuClick(ByVal sender As Object, ByVal e As
System.Windows.Forms.ToolStripItemClickedEventArgs)

        Dim MyForm As New frmEdit
        'Point to menu item clicked
        Select Case e.ClickedItem.Text
            Case "Open" : System.Diagnostics.Process.Start
(sDocumentName)
            Case "Edit"
                Dim I As Integer
                For I = 0 To ListView.SelectedItems.Count - 1
                    MyForm.MyPropertyMydata = ListView.SelectedItems
(I).Tag
                Next
                MyForm.Show()
                'now we have to clear and rebuild the items in the
Listview
                Dim node = TreeView.SelectedNode
                Dim nodeID = node.row("ID")
                LoadListView(nodeID)
            Case "Delete" : MsgBox("Delete")
        End Select

    End Sub

We would need to see the code for the LoadListView method to offer any
help.
 
C

Cor Ligthert[MVP]

Marco,

All modern program languages for User Interface are event driven this is
even for a Webprogramma although it is there as it is not Ajax mostly only
the commit button like in old non intelligent terminals.

This means that they act on what a user does.

Therefore you have to know which keys your user clicks and that is not only
the menu button.

By the way, I see no handler in the method that should handle the
menustripclick

Cor
 
J

James Hahn

At the time that your refresh code executes, the edit is not completed, so
no changes will be shown.

Your edit form should be a dialog (so it has a Cancel and OK button, and
returns a result code) and you should show it modally. Something like

if MyForm.ShowDialog() = DialogResult.OK then
'now we have to clear and rebuild the items in the ListView
Dim node = TreeView.SelectedNode
Dim nodeID = node.row("ID")
LoadListView(nodeID)
else
'undo any changes
end if
 
C

Co

At the time that your refresh code executes, the edit is not completed, so
no changes will be shown.

Your edit form should be a dialog (so it has a Cancel and OK button, and
returns a result code) and you should show it modally.  Something like

if MyForm.ShowDialog() = DialogResult.OK then
                'now we have to clear and rebuild the items in the ListView
                Dim node = TreeView.SelectedNode
                Dim nodeID = node.row("ID")
                LoadListView(nodeID)
else
                'undo any changes
end if

This is the code I use for the Listview:

Public Sub LoadListView(ByVal tblID As Integer)
' Add items to the listview based on the selected item in the
treeview

Dim lvItem As ListViewItem
ListView.Items.Clear()

Dim sql As String = "SELECT * FROM Bestanden WHERE lokatie=" &
tblID
Dim cmd As New OleDbCommand(sql, conn)
Dim dr As OleDbDataReader
conn.Open()
dr = cmd.ExecuteReader()

Do While (dr.Read())
lvItem = ListView.Items.Add(dr.Item("filenaam"))
lvItem.Tag = dr.Item("Id")
lvItem.SubItems.AddRange(New String() {dr.Item("grootte"),
dr.Item("auteur"), dr.Item("datum_gemaakt"), FixNull(dr.Item
("datum_gewijzigd")), FixNull(dr.Item("status"))})
lvItem.ImageIndex = dr.Item("extensie")
Loop
ListView.AutoResizeColumns
(ColumnHeaderAutoResizeStyle.HeaderSize)
dr.Close()
conn.Close()

End Sub

Marco
 
B

Branco

Marco said:
I have a Listview with filenames. When I click the edit menu the form
to edit data is opened.
When I change the file and close the form I want to rebuild the
listview holding the data so the changes are seen
at once, my code doesn't do that:

Private Sub CMenuClick(ByVal sender As Object, ByVal e As
System.Windows.Forms.ToolStripItemClickedEventArgs)

        Dim MyForm As New frmEdit
        'Point to menu item clicked
        Select Case e.ClickedItem.Text
            Case "Open" : System.Diagnostics.Process.Start
(sDocumentName)
            Case "Edit"
                Dim I As Integer
                For I = 0 To ListView.SelectedItems.Count - 1
                    MyForm.MyPropertyMydata = ListView.SelectedItems
(I).Tag
                Next
                MyForm.Show()
                'now we have to clear and rebuild the items in the
Listview
                Dim node = TreeView.SelectedNode
                Dim nodeID = node.row("ID")
                LoadListView(nodeID)
            Case "Delete" : MsgBox("Delete")
        End Select

    End Sub
<snip>

As already told by James Hahn, the command "MyForm.Show()" executes
and returns immediatly even while "MyForm" is still loading.
Therefore, when you start updating the listview, odds are that the
form didn't even show yet.

What you need, as James pointed out, is to either block the code until
your form closes (in this case you'd use "MyFor.ShowDialog", as
suggested), or, if having the form open modally isn't an option, then
you may declare the form "WithEvents", and have it raise some specific
event when the items are saved. In *that* event handler, then, you'd
update the list view.

<example>
'in the edit form (MyForm, as you named it)
Public Event EditOk(Sender As Object)

Sub Save()
'Save the data to the db...
'raise the event
RaiseEvent EditOk(Me)
'...
End Sub

'in the form with the list view:
Protected WithEvents EditForm As MyForm

Private Sub EditForm_OnEditOk(Sender As Object) _
Handles EditForm.EditOk
'... update your list view here
End Sub

Sub Form_Load(...) Handles Form.Load
'... create the form MyForm and keep it hidden;
'... assign it to the EditForm variable
EditForm = MyForm
'...
End Sub

'Inside your menu handling method:
'...
Case "Edit"
Dim I As Integer
For I = 0 To ListView.SelectedItems.Count - 1
MyForm.MyPropertyMydata = ListView.SelectedItems(I).Tag
Next
MyForm.Show()
Case "Delete"...
</example>

Now, a few issues:

a) It seems you are using an auto form variable for the MyForm
variable. This is generally considered a bad practice. It is
recommended that you initialize and instanciate the form yourself.

b) You are selecting the alternatives of your Select Case using
hardwired strings read from the Text property of the menu that was
clicked. Don't. If you change any text there, your code will break.
Instead, I suggest you use the item names in an If ... then ...
elseif... sequence:

<example>
Dim Item As ToolStripItem = e.ClickedItem
If Item Is OpenToolStripMenu Then
'menu Open
'...
ElseIf Item is EditToolStripMenu Then
'menu edit
'...
ElseIf Item Is DeleteToolStripMenu Then
'menu delete
'...
End If
</example>

Hope this helped.

Regards,

Branco.
 
C

Co

<snip>

As already told by James Hahn, the command "MyForm.Show()" executes
and returns immediatly even while "MyForm" is still loading.
Therefore, when you start updating the listview, odds are that the
form didn't even show yet.

What you need, as James pointed out, is to either block the code until
your form closes (in this case you'd use "MyFor.ShowDialog", as
suggested), or, if having the form open modally isn't an option, then
you may declare the form "WithEvents", and have it raise some specific
event when the items are saved. In *that* event handler, then, you'd
update the list view.

<example>
 'in the edit form (MyForm, as you named it)
  Public Event EditOk(Sender As Object)

  Sub Save()
    'Save the data to the db...
    'raise the event
    RaiseEvent EditOk(Me)
    '...
  End Sub

  'in the form with the list view:
  Protected WithEvents EditForm As MyForm

  Private Sub EditForm_OnEditOk(Sender As Object) _
  Handles EditForm.EditOk
    '... update your list view here
  End Sub

  Sub Form_Load(...) Handles Form.Load
    '... create the form MyForm and keep it hidden;
    '... assign it to the EditForm variable
    EditForm = MyForm
    '...
  End Sub

  'Inside your menu handling method:
  '...
  Case "Edit"
    Dim I As Integer
    For I = 0 To ListView.SelectedItems.Count - 1
      MyForm.MyPropertyMydata = ListView.SelectedItems(I).Tag
    Next
    MyForm.Show()
  Case "Delete"...
</example>

Now, a few issues:

a) It seems you are using an auto form variable for the MyForm
variable. This is generally considered a bad practice. It is
recommended that you initialize and instanciate the form yourself.

b) You are selecting the alternatives of your Select Case using
hardwired strings read from the Text property of the menu that was
clicked. Don't. If you change any text there, your code will break.
Instead, I suggest you use the item names in an If ... then ...
elseif... sequence:

<example>
  Dim Item As ToolStripItem = e.ClickedItem
  If Item Is OpenToolStripMenu Then
  'menu Open
    '...
  ElseIf Item is EditToolStripMenu Then
  'menu edit
    '...
  ElseIf Item Is DeleteToolStripMenu Then
  'menu delete
    '...
  End If
</example>

Hope this helped.

Regards,

Branco.

Branco,

thanks for the explanation, I like it.

The only part I have some problems with is:

'in the form with the list view:
Protected WithEvents EditForm As MyForm

Private Sub EditForm_OnEditOk(Sender As Object) _
Handles EditForm.EditOk
'... update your list view here
End Sub

Sub Form_Load(...) Handles Form.Load
'... create the form MyForm and keep it hidden:
'... assign it to the EditForm variable
EditForm = MyForm
'...
End Sub

First of all I get a warning: "Type MyForm is not defined" here:
Protected WithEvents EditForm As MyForm

I dont know what to put between the brackets here: Sub Form_Load(...)
Handles Form.Load

Marco
 
B

Branco

Marco wrote:
thanks for the explanation, I like it.

You're welcome.
The only part I have some problems with is:

 'in the form with the list view:
  Protected WithEvents EditForm As MyForm

  Private Sub EditForm_OnEditOk(Sender As Object) _
  Handles EditForm.EditOk
    '... update your list view here
  End Sub

  Sub Form_Load(...) Handles Form.Load
    '... create the form MyForm and keep it hidden:
    '... assign it to the EditForm variable
    EditForm = MyForm
    '...
  End Sub

First of all I get a warning: "Type MyForm is not defined" here:
Protected WithEvents EditForm As MyForm

I dont know what to put between the brackets here: Sub Form_Load(...)
Handles Form.Load

The code presented earlier was just an example to guide you, not
something to cut and paste verbatim into your own code =))

Nevertheless, here's a more detailed description of what I'm
suggesting:

a) In the form that edits the items (which you called MyForm, in your
code), declare an event to notify that the new data was saved:

Public Event EditOk(Sender As Object)

b) In that same form, after you have saved the items, raise the event:

RaiseEvent EditOk(Me)

c) Now, in your main form (the one with the listview), declare a
variable to capture the events of the editing form:

Protected WithEvents EditForm As MyForm

** Notice that in your code you refer to that form as "MyForm". I
thought "MyForm" was also the name of the form type. If it's not, use
the appropriate type name. That is, if the type name of your editing
form is actually "Form2" or whatever, use *that* in place of "MyForm":

Protected WithEvents EditForm As Form2

d) Go to the code view for the main form. You'll notice two combo
boxes above the code window. The one to the left contains all objects
inside your form. Open it and you will see a reference to the EditForm
variable that was declared in the previous step. Select it, and the
combo box to the right will be populated with the events exposed by
the editing form. Locate and select the EditOk event, and the IDE will
automatically create a handler for that event.

e) In the handler created in the last step, put the logic to refresh
the list view.

f) Now you need to assign a value for the variable EditForm that was
declared in step (c) above, so your main form can "see" the event
raised by your editing form. Somewhere in your code you must have a
line that says:

EditForm = MyForm

** If the EditForm variable is not assigned correctly, your main form
won't capture the events raised by your editing form.

** I'm assuming you never unload the edit form. If that is the case,
the best place to initialize the EditForm variable would be in the
Load event of your main form. Other than that, it will be wherever you
initialize your "MyForm" variable.

** To create the load event for the main form (cough, cough), go to
design view, double click in a blank area of the form and -- presto!
-- the load event is automatically created for you. =)))

Hope that helped.

Regards,

Branco.
 
C

Co

Marco wrote:



You're welcome.









The code presented earlier was just an example to guide you, not
something to cut and paste verbatim into your own code =))

Nevertheless, here's a more detailed description of what I'm
suggesting:

a) In the form that edits the items (which you called MyForm, in your
code), declare an event to notify that the new data was saved:

  Public Event EditOk(Sender As Object)

b) In that same form, after you have saved the items, raise the event:

   RaiseEvent EditOk(Me)

c) Now, in your main form (the one with the listview), declare a
variable to capture the events of the editing form:

  Protected WithEvents EditForm As MyForm

** Notice that in your code you refer to that form as "MyForm". I
thought "MyForm" was also the name of the form type. If it's not, use
the appropriate type name. That is, if the type name of your editing
form is actually "Form2" or whatever, use *that* in place of "MyForm":

  Protected WithEvents EditForm As Form2

d) Go to the code view for the main form. You'll notice two combo
boxes above the code window. The one to the left contains all objects
inside your form. Open it and you will see a reference to the EditForm
variable that was declared in the previous step. Select it, and the
combo box to the right will be populated with the events exposed by
the editing form. Locate and select the EditOk event, and the IDE will
automatically create a handler for that event.

e) In the handler created in the last step, put the logic to refresh
the list view.

f) Now you need to assign a value for the variable EditForm that was
declared in step (c) above, so your main form can "see" the event
raised by your editing form. Somewhere in your code you must have a
line that says:

   EditForm = MyForm

** If the EditForm variable is not assigned correctly, your main form
won't capture the events raised by your editing form.

** I'm assuming you never unload the edit form. If that is the case,
the best place to initialize the EditForm variable would be in the
Load event of your main form. Other than that, it will be wherever you
initialize your "MyForm" variable.

** To create the load event for the main form (cough, cough), go to
design view, double click in a blank area of the form and -- presto!
-- the load event is automatically created for you. =)))

Hope that helped.

Regards,

Branco.

Branco,

thanks again for the info.
The code is running now but I still see no differences in the newly
loaded Listview.
I'm beginning to think that maybe the database isn't yet updated when
I refill the Listview.
Is that possible?

Marco
 
C

Co

Branco,

thanks again for the info.
The code is running now but I still see no differences in the newly
loaded Listview.
I'm beginning to think that maybe the database isn't yet updated when
I refill the Listview.
Is that possible?

Marco

If I put in a messagebox when I refill the Listview it DOES show me
the new values.
Furthermore when I try to load the frmEdit for the second time I get
an error saying:

Cannot access a disposed object.
Object name: 'frmEdit'.

Marco
 
B

Branco

Marco wrote:
If I put in a messagebox when I refill the Listview it DOES show me
the new values.
Furthermore when I try to load the frmEdit for the second time I get
an error saying:

Cannot access a disposed object.
Object name: 'frmEdit'.
<snip>

Hi, Marco!

I guess it's time to show us some more code. The error message you are
getting is because you are probably unloading the edit form when
finishing, and then you need to recreate it before it can be used
again.

Also, you're not seeing the listview updates probably because your
event handler isn't being called.

All this revolves around the way you are creating and opening the edit
form. I guess if you post the code where you create the form and call
it, we (me or someone else from the list) will be able to help.

Best regards,

Branco.
 
C

Co

Marco wrote:




<snip>

Hi, Marco!

I guess it's time to show us some more code. The error message you are
getting is because you are probably unloading the edit form when
finishing, and then you need to recreate it before it can be used
again.

Also, you're not seeing the listview updates probably because your
event handler isn't being called.

All this revolves around the way you are creating and opening the edit
form. I guess if you post the code where you create the form and call
it, we (me or someone else from the list) will be able to help.

Best regards,

Branco.

Branco,

I do recreate the Edit form when I reopen it.
I think the problem is that there is a delay in updating the database.

<----------- Explorer.vb ---------------------->
Protected WithEvents EditForm As frmEdit

Opening the edit form:

Private Sub CMenuClick(ByVal sender As Object, ByVal e As
System.Windows.Forms.ToolStripItemClickedEventArgs)

'Point to menu item clicked

Select Case e.ClickedItem.Text
Case "Open" : System.Diagnostics.Process.Start
(sDocumentName)

Case "Edit"
Dim MyForm As New frmEdit
EditForm = MyForm
Dim I As Integer
For I = 0 To ListView.SelectedItems.Count - 1
MyForm.MyPropertyMydata = ListView.SelectedItems
(I).Tag
Next
MyForm.Show()
.........

Catching the Event:
Private Sub EditForm_OnEditOk(ByVal Sender As Object) _
Handles EditForm.EditOk

'now we have to clear and rebuild the items in the Listview
Dim node = TreeView.SelectedNode
Dim nodeID = node.row("ID")
LoadListView(nodeID)

End Sub

<--------------- frmEdit -------------------->

Saving the data in the edit form:
Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles btnSave.Click
SaveDocumentDetails(iD)
Me.Close()
End Sub

Sub SaveDocumentDetails(ByVal DocID As Integer)

Dim sql As String = "SELECT * FROM Bestanden WHERE Id=" &
DocID
Dim strTable As String = "Bestanden"
Dim da As New OleDb.OleDbDataAdapter(sql, conn)
Dim cb As New OleDb.OleDbCommandBuilder(da)
Dim ds As New DataSet

Try
da.SelectCommand = New OleDb.OleDbCommand(sql, conn)
da.Fill(ds, strTable)

Dim dr As DataRow
For Each dr In ds.Tables(0).Rows
dr.Item("kenmerk") = tbKenmerk.Text
dr.Item("status") = cboStatus.Text
dr.Item("auteur") = tbAuteur.Text
dr.Item("datum_gewijzigd") = tbGewijzigd.Text
dr.Item("expires") = tbVerloopt.Text
dr.Item("hddlokatie") = tbHDDLokatie.Text
dr.Item("samenvatting") = tbSamenvatting.Text
dr.Item("soort") = cboSoort.Text
dr.Item("rubricering") = cboRubri.Text
dr.Item("inuit") = cboInUit.Text
Next

'sent the updated dataSet to the database
da.Update(ds, strTable)

Catch oException As OleDbException
MessageBox.Show(oException.Message)

Catch oException As Exception
MessageBox.Show(oException.Message)

End Try
conn.Close()
RaiseEvent EditOk(Me)
End Sub

Regards
Marco
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top