1

I have a ListBox on a form that is bound to a BindingList<T> in code behind but is not displaying the items within the BindingList<T>.

XAML:

<Window x:Class="MessageServer.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MessageServer"
    Name="mainWindow" Title="Message Exchange Server" 
    Height="350" Width="525" Closing="Window_Closing">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>

        <ListBox Name="OutputList" Grid.Row="0" />
        <ListBox Name="Connected" Grid.Row="1" ItemsSource="{Binding ElementName=mainWindow, Path=ConnectedClients}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Path=FullIPAddress}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

    </Grid>
</Grid>

CodeBehind:

private BindingList<Client> _ConnectedClients;
public BindingList<Client> ConnectedClients
{
    get { return _ConnectedClients; }
    set { _ConnectedClients = value; }
}

public class Client : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private TcpClient _tcpClient;
    public TcpClient tcpClient
    {
        get { return _tcpClient; }
        set
        {
            _tcpClient = value;
            NotifyPropertyChanged();
        }
    }

    public string FullIPAddress
    {
        get { return _tcpClient.Client.RemoteEndPoint.ToString(); }
    }

    public string IPAddress
    {
        get { return _tcpClient.Client.RemoteEndPoint.ToString().Split(':').ElementAt(0); }
    }

    public string PortNumber
    {
        get { return _tcpClient.Client.RemoteEndPoint.ToString().Split(':').ElementAt(1); }
    }

    public Client(TcpClient tcpClient)
    {
        this.tcpClient = tcpClient;
        NotifyPropertyChanged();
    }

    private void NotifyPropertyChanged()
    {
        NotifyPropertyChanged("tcpClient");
        NotifyPropertyChanged("FullIPAddress");
        NotifyPropertyChanged("IPAddress");
        NotifyPropertyChanged("PortNumber");
    }

    private void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Any Ideas why the list box is not displaying the items? Not sure if this is worth mentioning but When added items to the BindingList this is done on a seperate thread to the UI Thread. but I have tried using Dispatcher.BeginInvoke() but still does not work...

H.B.
  • 166,899
  • 29
  • 327
  • 400
Andy Clark
  • 3,363
  • 7
  • 27
  • 42
  • 3
    It sounds like you really want to use ObservableCollection. It sounds like BindingList should work, but on this SO post they seem say ObservableCollection is for WPF and BindingList for Winforms: http://stackoverflow.com/questions/4284663/difference-between-observablecollection-and-bindinglist – ShelbyZ Nov 08 '11 at 17:12
  • I changed the BindingList to be of type ObservableCollection and this worked with no problems, the only change i had to make was when adding/removing items from the list i had to do it on the UI thread which is easily achieved (for those who do not know) using... Dispatcher.BeginInvoke(new Action(() => ConnectedClients.Add(client))); – Andy Clark Nov 08 '11 at 17:29

3 Answers3

3

It sounds like you really want to use ObservableCollection. It sounds like BindingList should work, but on this SO post they seem say ObservableCollection is for WPF and BindingList for Winforms: Differences between BindingList and ObservableCollection

Community
  • 1
  • 1
ShelbyZ
  • 1,494
  • 1
  • 14
  • 32
2

Try using an ObservableCollection<T>. It was designed specifically for WPF.

Nick O
  • 3,716
  • 6
  • 38
  • 50
  • Guess I should have read the comments on you question. @ShelbyZ you should have posted as answer instead of putting it in a comment. – Nick O Nov 08 '11 at 17:37
  • Mine was a guess on direction to go as I didn't have the time to work it out myself. – ShelbyZ Nov 08 '11 at 17:40
1

You are trying to bind to Window.ConnectedClients, which is a property that doesn't exist.

You need to change your binding to DataContext.ConnectedClients to bind to Window.DataContext.ConnectedClients

ItemsSource="{Binding ElementName=mainWindow, Path=DataContext.ConnectedClients}"
Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Alternatively, just bind to ConnectedClients, since it is apparently a property of the instance in the DataContext – flq Nov 08 '11 at 17:16
  • @Flq Yes that would work using the given code sample, but it wouldn't work if this is a simplified code sample and the ListBox DataContext is not the same as the Window DataContext – Rachel Nov 08 '11 at 17:26
  • @Rachel not sure what you mean when you say it is not a property that exists?? The list is a property of the Window class and does exist surely?? – Andy Clark Nov 08 '11 at 17:33
  • @MrsNezbit Sorry, thought you were using the MVVM design pattern. Since you're not using it and the collection is a property on your Window class, the binding is fine. – Rachel Nov 08 '11 at 18:19