locked
Binding a WPF listview to a DataTable RRS feed

  • General discussion

  • Hi All,

    I have this code,

    listView.DataContext = sampleStore;
    listView.SetBinding(ListView.ItemsSourceProperty, new Binding());

    Where listView is my ListView control, and sampleStore is my DataTable.

    When more items are added into the DataTable the ListView is not updated on the screen. The items appear when they are first bound though, but then that is it.

    The reason I want to do this by code is that my WPF app has a tab control, and dynamically more tabs can be present depending on the data flowing through the system. Each tab has a listview control, and each listview control creates dynamically the columns that are to be displayed.

    Any ideas?
    • Changed type Marco Zhou Friday, August 8, 2008 9:58 AM OP doesn't revert back
    Friday, August 1, 2008 10:54 PM

All replies

  • Give thanks to Sneha Singla provides this explanation:

    WPF does support the change notification for ADO.NET data, the CollectionView implementation which bridges between data and View(UI) will connect to the underlying DataView of ADO.NET data, hook up to its ListChanged event, and when the ADO.NET data changed, the CollectionView implementation will receive the change notification and update the UI accordingly.

    This is one work sample:

    <Window x:Class="BindingADONET.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        Title="Window1" Height="300" Width="300"
        <DockPanel> 
            <Button Width="120" Height="30" Content="Add" Name="btn" DockPanel.Dock="Top"/> 
            <ListBox ItemsSource="{Binding}" DisplayMemberPath="ChildItem"/> 
        </DockPanel> 
    </Window> 

    namespace BindingADONET 
        public partial class Window1 : Window 
        { 
            public Window1() 
            { 
                InitializeComponent(); 
                DataTable dataTable = MakeChildTable(); 
                this.DataContext = ((IListSource)dataTable).GetList(); 
                this.btn.Click += delegate 
                { 
                    DataRow row = dataTable.NewRow(); 
                    row["childID"] = 50; 
                    row["ChildItem"] = "ChildItem " + 50; 
                    dataTable.Rows.Add(row); 
                }; 
            } 
     
            private DataTable MakeChildTable() 
            { 
                DataTable table = new DataTable("childTable"); 
                DataColumn column; 
                DataRow row; 
     
                column = new DataColumn(); 
                column.DataType = System.Type.GetType("System.Int32"); 
                column.ColumnName = "ChildID"
                column.Caption = "ID"
     
                table.Columns.Add(column); 
     
                column = new DataColumn(); 
                column.DataType = System.Type.GetType("System.String"); 
                column.ColumnName = "ChildItem"
                column.Caption = "ChildItem"
                table.Columns.Add(column); 
     
                for (int i = 0; i <= 4; i++) 
                { 
                    row = table.NewRow(); 
                    row["childID"] = i; 
                    row["ChildItem"] = "Item " + i; 
                    table.Rows.Add(row); 
                } 
                return table; 
            } 
        } 

    Hope this helps


    Yiling, MVP(Visual C++)
    Yiling, MVP(Visual C++)
    Saturday, August 2, 2008 2:37 AM
  • Thanks for that, Still having problems though.

    I have to do my binding in code because I am dynamically creating these ListView controls, and there can be any number off them on my tabs.

    After your example I tried 3 things (similar to what I had initially),

    NOTE: The sampleStore variable there is the DataTable which already has data in it at this stage.

    1)

    ListView listView = new ListView();
    listView.ItemsSource = ((IListSource)sampleStore).GetList();

    2)

    ListView listView = new ListView();
    listView.ItemsSource = sampleStore.DefaultView;

    3)

    ListView listView = new ListView();
    listView.DataContext = ((IListSource)sampleStore).GetList();
    BindingOperations.SetBinding(listView, ListView.ItemsSourceProperty, new Binding());

    They all actually do the same thing. Update once at the beginning, and never again.

    Any other ideas? I have no XAML to show you because I am not using any for this part. The ListView is being added to a StackPanel, and the StackPanel added to a TabItem.

    How am I supposed to dig in and see exactly what is wrong?

    You mentioned the CollectionView implementation. I don't understand how this is relavant. Please explain. I think you are telling me this is a structure that is in place, and I don't need to do anything more. Something I am doing seems to have broken that.
    Saturday, August 2, 2008 11:00 AM
  • I can't reproduce your problem. Exactlly. ADO.NET's DataView already implement its own form of notification with IBindingList interface. Data binding engine will listen to ListChanged event. ListChangedEventArgs contain a ListChangedType enum with values such as “ItemAdded”, “ItemDeleted”, and “ItemChanged”.

    It should be better you can have one simple demo.

    Hope this helps.

    Yiling, MVP(Visual C++)
    Saturday, August 2, 2008 11:51 AM
  • We are changing the issue type to “Comment” because you have not followed up with the necessary information. If you have more time to look at the issue and provide more information, please feel free to change the issue type back to “Question” by clicking the "Options" link at the top of your post, and selecting "Change Type" menu item from the pop menu. If the issue is resolved, we will appreciate it if you can share the solution so that the answer can be found and used by other community members having similar questions.

     

    Thank you!

    Friday, August 8, 2008 9:58 AM