Results 1 to 14 of 14

Thread: DataBinding An ObservableCollection(Of string) to a Label

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    DataBinding An ObservableCollection(Of string) to a Label

    I am trying to bind the count of items in an ObservableCollection(Of string) to a label. I have not been able to find a clear explanation or example and it seems like it should be super simple. I just don't know VB. I usually work in C# and they are not interchangeable.
    I have a label named lblFileListCount. I want it to display the number of file names in the ObservableCollection. So I added this to the load method.

    Code:
    lblFileListCount.DataBindings.Add("Text", ResultFiles, ResultFiles.Count, False, DataSourceUpdateMode.OnPropertyChanged)
    I get this error.

    System.ArgumentException: 'Cannot bind to the property or column 0 on the DataSource.
    Parameter name: dataMember'
    What is wrong?

    Thanks
    Last edited by dday9; Nov 19th, 2021 at 12:12 PM.

  2. #2
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: DataBinding An ObservableCollection(Of string) to a Label

    You're using the DataBindings.Add method with the overload propertyName, dataSource, dataMember, formattingEnabled, and updateMode (documentation).

    Instead of using ResultFiles.Count, reference the actual property name:
    Code:
    lblFileListCount.DataBindings.Add("Text", ResultFiles, "Count", False, DataSourceUpdateMode.OnPropertyChanged)
    I would also encourage you to turn Option Strict on because I would think that it would've caused an error before you even compiled the code since the argument was expecting a String but you were providing it with an Integer.

    Edit - To explain your error message, the compiler was implicitly converting ResultFiles.Count to a String, which was returning 0. Since there is no property named "0" on ObservableCollection, it was failing.
    Last edited by dday9; Nov 19th, 2021 at 10:08 AM.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  3. #3

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    Thank you, dday9, for your reply. I did turn on Option Strict! I still get an error.

    'Cannot bind to the property or column Count on the DataSource.
    Parameter name: dataMember'
    This is the new line.

    Code:
    lblFileListCount.DataBindings.Add("Text", ResultFiles, "Count", DataSourceUpdateMode.OnPropertyChanged)
    Scott
    Last edited by dday9; Nov 19th, 2021 at 12:12 PM.

  4. #4
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    11,711

    Re: DataBinding An ObservableCollection(Of string) to a Label

    First thing, it looks like you're trying to use a different overload, but one that doesn't exist. Did you just forget to include the boolean value before the DataSourceUpdateMode in your second post or do you no longer want to set formattingEnabled?

    As far as your error, could you provide me with the variable declaration of ResultFiles?
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | Code Tags | Sword of Fury - Jameram

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,299

    Re: DataBinding An ObservableCollection(Of string) to a Label

    The NameOf operator allows you to use a String value but still get compile-time validation:
    vb.net Code:
    1. lblFileListCount.DataBindings.Add("Text", ResultFiles, NameOf(ResultFiles.Count), False, DataSourceUpdateMode.OnPropertyChanged)
    I'm not sure that that solves your issue though. Usually, you would provide a collection as a data source and specify a property of the items as the data member. It seems that the system is assuming that that is what you're doing but no such property exists on the items so it fails. I'm not sure how exactly you would specify that it's a property of the collection object itself and not a property of the items. You might have to create the Binding yourself first but I'm still not sure exactly how you would specify that it's the Count of the collection rather than of the items.

  6. #6

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    Quote Originally Posted by dday9 View Post
    First thing, it looks like you're trying to use a different overload, but one that doesn't exist. Did you just forget to include the boolean value before the DataSourceUpdateMode in your second post or do you no longer want to set formattingEnabled?

    As far as your error, could you provide me with the variable declaration of ResultFiles?

    There are three such labels.
    Code:
                lblFileListCount.DataBindings.Add("Text", ResultFiles, "Count", False, DataSourceUpdateMode.OnPropertyChanged)
                lblCompletedFiles.DataBindings.Add("Text", CompletedFiles, "Count", False, DataSourceUpdateMode.OnPropertyChanged)
                lblSkippedFilesCount.DataBindings.Add("Text", SkippedResults, "Count", False, DataSourceUpdateMode.OnPropertyChanged)
    All three observable collections are defined and all three are initialized in the constructor. All three are accessed through properties defined as below.
    Code:
        Public Property ResultFiles() As ObservableCollection(Of String)
            Get
                If _ResultFiles Is Nothing Then _ResultFiles = New Collection(Of String)
                Return _ResultFiles
            End Get
            Set(value As ObservableCollection(Of String))
                _ResultFiles = value
                RaisePropertyChanged("ResultFiles")
            End Set
        End Property
    These two bindings work fine.
    Code:
                lblStartTime.DataBindings.Add("Text", Me, "StartTime", DataSourceUpdateMode.OnPropertyChanged)
                lblVersion.DataBindings.Add("Text", Me, "Version", DataSourceUpdateMode.OnPropertyChanged)

  7. #7
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: DataBinding An ObservableCollection(Of string) to a Label

    The problem is that the property isn’t set when an item is added to the collection… But ObservableCollections do raise events when the collection changes…

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: DataBinding An ObservableCollection(Of string) to a Label

    Here’s how to make it work. It’s in c#… There are converters for vb

    Code:
    public class ViewModel: INotifyPropertyChanged
    {
        public ObservableCollection<string> MembersList { get; set; }
    
        public ViewModel()
        {
            MembersList = new ObservableCollection<string>();
            MembersList.CollectionChanged += collection_CollectionChanged;
            MembersList.Add("wfwef");
        }
    
        void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            Notify("MembersList.Count");
        }
    
        private void Notify(string propName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    }

  9. #9

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    What do you mean "The property isn't set..."? And the property does raise the property changed event. In C# you do not need to implement the Collection Changed event for a simple binding like this. You simply bind the collection count to the control. This is VB and there is no direct translation from C# to VB. At least I can't translate from C# to VB. I don't know VB well enough.

    I would like to see a working solution in VB. Is it not possible? I have found nothing on line. There are examples of binding a dataset to a grid view, etc. But I can't find a simple example of binding a property to a label.

    Thanks,

  10. #10
    Smooth Moperator techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,531

    Re: DataBinding An ObservableCollection(Of string) to a Label

    Code:
    public class ViewModel: INotifyPropertyChanged
    {
        public ObservableCollection<string> MembersList { get; set; }
    
        public ViewModel()
        {
            MembersList = new ObservableCollection<string>();
            MembersList.CollectionChanged += collection_CollectionChanged;
            MembersList.Add("wfwef");
        }
    
        void collection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            Notify("MembersList.Count");
        }
    
        private void Notify(string propName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    
    
        public event PropertyChangedEventHandler PropertyChanged;
    }
    Code:
    Public Class ViewModel Implements INotifyPropertyChanged
    
      Public Event PropertyChanged (PropertyChangedEventHandler)
    
      Public Property MembersList as ObservableCollection(Of String)
    
      Public Sub New()
        MembersList = new ObservableCollection(Of String)
        AddHandler MembersList.CollectionChanged, AddressOf collection_CollectionChanged
        MembersList.Add("QWERTY")
      End Sub
    
      Private Sub collection_CollectionChanged(sender object, e System.Collections.Specialized.NotifyCollectionChangedEventArgs)
        Notify("MembersList.Count")
      End Sub
    
      Private Sub Notify(propName String)
        if PropertyChanged is not null then
          PropertyChanged(me, new PropertyChangedEventArgs(propName)
        End If
      End Sub
    End Class
    Nice thing about .NET is that .NET is .NET is .NET...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  11. #11

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    What do you mean "The property isn't set..."? And the property does raise the property changed event. This is VB and there is no direct translation from C# to VB. At least I can't translate from C# to VB. I don't know VB well enough.

    I would like to see a working solution in VB. Is it not possible? I have found nothing on line. There are examples of binding a dataset to a grid view, etc. But I can't find a simple example of binding a property to a label.

    Thanks,

  12. #12

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    So my last reply is not here, but the previous one is here twice!

    Thanks for the translation. I have implemented INotifyPropertyChanged and I Raise the event when I add a file to the ResultFiles (at least it is called). But I added the event handler for the collection anyway and I call the notify property changed event. But that doesn't solve the original problem. The problem is that this
    Code:
     lblFileListCount.DataBindings.Add("Text", Me, "ResultFiles.Count", False, DataSourceUpdateMode.OnPropertyChanged)
    line throws an exception as described above. It may be a little different now. I have been trying different things while troubleshooting. In the latest revision I have decided to use a collection of FileInfo. That should make no difference because all I care about is the number of items in the collection.

    Thank you.

  13. #13
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: DataBinding An ObservableCollection(Of string) to a Label

    There's no need for binding. In your code, the property only changes when you set the whole collection. An ObservableCollection(Of String) has its own events you can use...

    Code:
    Public Class Form1
    
        Private ResultFiles As New ObservableCollection(Of String)
        Private CompletedFiles As New ObservableCollection(Of String)
        Private SkippedResults As New ObservableCollection(Of String)
    
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
            AddHandler ResultFiles.CollectionChanged, AddressOf collections_CollectionChanged
            AddHandler CompletedFiles.CollectionChanged, AddressOf collections_CollectionChanged
            AddHandler SkippedResults.CollectionChanged, AddressOf collections_CollectionChanged
        End Sub
    
        Private Sub collections_CollectionChanged(ByVal sender As Object, ByVal e As System.Collections.Specialized.NotifyCollectionChangedEventArgs)
            lblFileListCount.Text = ResultFiles.Count.ToString
            lblCompletedFiles.Text = CompletedFiles.Count.ToString
            lblSkippedFilesCount.Text = SkippedResults.Count.ToString
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            ResultFiles.Add("one")
            CompletedFiles.Add("one")
            SkippedResults.Add("one")
        End Sub
    
    End Class

  14. #14

    Thread Starter
    New Member
    Join Date
    Jul 2021
    Posts
    13

    Re: DataBinding An ObservableCollection(Of string) to a Label

    Thank you very much, .paul.! I cannot understand why this was so hard for me to get right. Thanks to you, it is working as desired.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width