0
votes

I'm having some issues with the ItemsSource property in WPF (for binding). I can't run my program while having the "ItemsSource="{Binding}" as a property for my ListBox. Although, if I remove it, the program runs fine but the binding doesn't work.

XAML:

<Window x:Class="TP1.EcranPrincipal"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TP1"
        mc:Ignorable="d"
        Background="CornflowerBlue"
        Title="" Height="400" Width="700">

    <Window.Resources>
        <DataTemplate x:Key="masterTemplate">
            <TextBlock
          Margin="4"
          Text="{Binding Description,UpdateSourceTrigger=PropertyChanged}"/>
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="2*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="2*"/>
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <TextBox Grid.Column="1" Grid.Row="0" Padding="5" VerticalContentAlignment="Center" Margin="10,10,90,0" TextWrapping="NoWrap" Text="" VerticalAlignment="Top" Grid.ColumnSpan="4"/>
        <Button x:Name="BoutonRechercher" Grid.Column="4" Grid.Row="0" Padding="5" Content="Rechercher" HorizontalAlignment="Left" Margin="88,9,0,0" VerticalAlignment="Top" Click="BoutonRechercher_Click" Width="75"/>

        <!-- 1st TextBoxes' column -->
        <TextBox x:Name="Nom" Text="{Binding Nom,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="1" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Telephone" Text="{Binding Téléphone,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="2" Margin="0, 0, 10, 10"  VerticalContentAlignment="Center" Padding="5,0" />
        <TextBox x:Name="Adresse1" Text="{Binding Adresse1,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="3" Margin="0, 0, 10, 10" Grid.ColumnSpan="3" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Adresse2" Text="{Binding Adresse2,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="4" Margin="0, 0, 10, 10" Grid.ColumnSpan="3" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Ville" Text="{Binding Ville,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="5" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Pays" Text="{Binding Pays,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="2" Grid.Row="6" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>

        <!-- 2nd TextBoxes' column -->
        <TextBox x:Name="Prenom" Text="{Binding Prénom,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="1" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Courriel" Text="{Binding Courriel,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="2" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>
        <TextBox x:Name="Province" Text="{Binding Province,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="5" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>
        <TextBox x:Name="CodePostal" Text="{Binding CodePostal,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Grid.Column="4" Grid.Row="6" Margin="0, 0, 10, 10" VerticalContentAlignment="Center"/>

        <ListBox x:Name="ListeBoxUtilisateurs" ItemsSource="{Binding}" ItemTemplate="{StaticResource masterTemplate}" IsSynchronizedWithCurrentItem="True" HorizontalAlignment="Left" Height="349" Margin="10,10,0,0" VerticalAlignment="Top" Width="153" Grid.RowSpan="7"/>


    </Grid>
</Window>

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

// StreamReader/Writer:
using System.IO;
using System.ComponentModel;

namespace TP1
{
    /// <summary>
    /// Logique d'interaction pour EcranPrincipal.xaml
    /// </summary>
    public partial class EcranPrincipal : Window
    {

        // Required variables to read the file
        List<String> elementsLignes = new List<String>();
        List<Utilisateur> utilisateurs = new List<Utilisateur>();
        Collection Coll = new Collection();



        public EcranPrincipal()
        {
            InitializeComponent();
            this.DataContext = Coll;
            ListBox listeUtilisateurs = ListeBoxUtilisateurs;

            var reader = new StreamReader(File.OpenRead("TextFile.txt"));
            int nbUtilisateurs = 0;

            Console.WriteLine(reader.ReadLine());

            while (reader.ReadLine() != null)
            {
               // Reading the file, this works fine
            }
        }


        private ListBoxItem selectedItem;
        public ListBoxItem SelectedItem
        {
            get { return selectedItem; }
            set { selectedItem = value; }
        }
    }
}

Everytime I run my program, I get this Items collection must be empty before using ItemsSource error. Anyone figured out what my problem is?

1
What is // Reading the file, this works fine? Are you adding anything to listeUtilisateurs.Items there? - 15ee8f99-57ff-4f92-890c-b56153
You should populate ListeBoxUtilisateurs with an ObservableCollection and in no other way. Just bind its ItemsSource to the ObservableCollection. Add items to the ObservableCollection, remove them from it, clear it, etc. The ListBox will update accordingly. - 15ee8f99-57ff-4f92-890c-b56153

1 Answers

2
votes

Your Bindings seem off, in my opinion.

  1. you are declaring that the DataContext shall be an empty Coll - maybe you just dropped the code.
  2. You should set the DataContext before the call InitializeComponent() to prevent heavy - unnecessary - DataContextChanged Event handling
  3. Your TextBoxes than bind to that DataContext - why should a Collection have properties like Nom, Téléphone and so on
  4. Why do you have the member SelectedItem when you never use it?

I would recommend the following members in your window:

public ObservableCollection<object> Coll { get; set; }
public object SelectedItem { get; set; }

(Change object to your actualy type you have)

Maybe - maybe because I cannot tell if the properties are inside the object of the listview or not - change all your TextBoxes to have the following binding:

<TextBox x:Name="Nom" Text="{Binding SelectedItem.Nom, UpdateSourceTrigger=PropertyChanged}" />

Change your ListBox to this:

<ListBox x:Name="ListeBoxUtilisateurs" ItemsSource="{Binding Coll}" SelectedItem="{Binding SelectedItem}" ItemTemplate="{StaticResource masterTemplate}" HorizontalAlignment="Left" Height="349" Margin="10,10,0,0" VerticalAlignment="Top" Width="153" Grid.RowSpan="7"/>