Click here to Skip to main content
15,910,872 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi

I have been searching fo days now to resolve a binding issue i am having and every solution i found has come up short and not worked. All i can think of is that what i am trying to do is not supported and cannot be done (But I Doubt it.) Here is the scenario.....

I have a class called SupportCall
Within the class there is an ObservableCollection of a SupportAction object.
Based on the security rights of the user viewing the support call they can see All SupportAction's or just public ones. i expose the lists By having two properties as shown below.

Public ReadOnly Property Actions() As IList(Of SupportAction)
 Get
  Try

      Dim found As IQueryable(Of SupportAction) = Nothing
      found = From a As SupportAction In _actions.AsQueryable _
              Order By a.CreateDate Descending
      Return found.ToObservableCollection

   Catch ex As Exception
      Throw ex
   End Try
  End Get
 End Property


And....

Public ReadOnly Property ActionsGeneral() As IList(Of SupportAction)
 Get
   Try

      Dim found As IQueryable(Of SupportAction) = Nothing
      found = From a As SupportAction In _actions.AsQueryable _
      Where a.IsInternal = False Order By a.CreateDate Descending
      Return found.ToObservableCollection

   Catch ex As Exception
       Throw ex
    End Try
 End Get
End Property


i use an extention fucntion to convert the IQueryable to an ObservableCollection. The function is below.....

XML
<Extension()> _
Public Function ToObservableCollection(Of T)(ByVal MyCollection As IEnumerable(Of T)) As ObservableCollection(Of T)
  Try

    Dim c As New ObservableCollection(Of T)(MyCollection)
    Return c

   Catch ex As Exception
     Throw New NotSupportedException(ex.InnerException.Message)
   End Try

End Function


In my front end WPF application i use one of the properties to populate a datagrid like so....

dgActions.ItemsSource = _CurrentCall.Actions


i have a button that then adds a new action. This is done via a method within the SupportCall Object. The method is below....

Public Sub AddAction(ByVal UserID As Integer, ByVal Description As String, ByVal HasAtt As Boolean, ByVal AttFileName As String, ByVal Type As Integer, ByVal Internal As Boolean)
           Try
               Dim sa As New SupportAction(_callid, UserID, Description, HasAtt, AttFileName, Type, Internal, _datasource, _DSusername, _DSPassword)
               _actions.Add(sa)
               NotifyPropertyChanged("Actions")
               NotifyPropertyChanged("ActionsGeneral")
           Catch ex As Exception
               Throw ex
           End Try
       End Sub


my problem is that when i fire the AddAction sub i expect the WPF datagrid to reflect the change as its source has been set to be an ObservableCollection. Unfortunatley nothing happens. I have to close the form and reload the view the new action in the grid. I need to be able to bind the Datagrid.ItemSource dynamically in code rather than XAML to apply user security features. Can anyone tell me what the hell i am doing wrong here because i just cant get it to work.... Please Help Someone......
Posted

Have you debugged, what happens when you call NotifyPropertyChanged("Actions"). Is the Actions() property really called. To be sure, place a breakpoint inside the Actions property, just in case the debugger cannot jump to the property for some reason.

If it's called, you could try what happens if you add a new boolean to the class and using that you first return a null as the collection and then the actual collection. So something like:

VB
Public ReadOnly Property Actions() As IList(Of SupportAction)
 Get
  If _returnEmpty Then
     Return null
  End If
  Try

      Dim found As IQueryable(Of SupportAction) = Nothing
      found = From a As SupportAction In _actions.AsQueryable _
              Order By a.CreateDate Descending
      Return found.ToObservableCollection

   Catch ex As Exception
      Throw ex
   End Try
  End Get
 End Property

And
VB
Public Sub AddAction(ByVal UserID As Integer, ByVal Description As String, ByVal HasAtt As Boolean, ByVal AttFileName As String, ByVal Type As Integer, ByVal Internal As Boolean)
           Try
               Dim sa As New SupportAction(_callid, UserID, Description, HasAtt, AttFileName, Type, Internal, _datasource, _DSusername, _DSPassword)
               _actions.Add(sa)

               _returnEmpty = true
               NotifyPropertyChanged("Actions")
               _returnEmpty = false
               NotifyPropertyChanged("Actions")

               NotifyPropertyChanged("ActionsGeneral")
           Catch ex As Exception
               Throw ex
           End Try
       End Sub
 
Share this answer
 
Bindings don't like dramatic changes. Looking at your code, without testing it, it appears that you're passing a new collection every time the Extension funtion is called. This is causing the binding to become broken.

There are two (2) possible solutions:
1. Issue a bind command in code-behind after calling the extension to fix the brake;
2. Pass a concrete ObservableCollection to the extension and use the Clear method to empty the collection before filling.

The second option is the one that I would use.
 
Share this answer
 
Hi Guys

just wanted you to know that you fixed my issue. I had already debugged the code and new that the events were firing correctly. I took Graeme's advice and tried option two and tried to clear and populate the original ObservableCollection. I tried to remember that i was only using link to sort and filter without having to use delegates. So i changed my code to below and all works perfectly so thanks. I have included the code solution incase anyone else come against the same issue.

Public ReadOnly Property Actions() As IList(Of SupportAction)
            Get
                Try

                    SortActions()
                    Return _actions

                Catch ex As Exception
                    Throw ex
                End Try
            End Get
        End Property

        Private Sub SortActions()
            Try
                Dim ReturnItems As IList(Of SupportAction)
                Dim found As IQueryable(Of SupportAction) = Nothing
                found = From a As SupportAction In _actions.AsQueryable Order By a.CreateDate Descending
                ReturnItems = found.ToList
                _actions.Clear()
                For Each sa As SupportAction In ReturnItems.ToObservableCollection
                    _actions.Add(sa)
                Next

            Catch ex As Exception
                Throw ex
            End Try
        End Sub
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900