Binding DataTable using ObservableCollection to ListView

2.8k views Asked by At

I see this is a common problem as I have went over many posts but can't figure out solution for my one. I'm migrating from WinForms to WPF and have a DataSet that needs to be bind to ListView. I was trying to follow this solution: https://stackoverflow.com/a/5880315/2920121 but without success. Please note I'm new to C# and .NET.

Here's my WPF and WinForms code:

WinForms:

CmdStrFg = "SELECT dbname, Version, UpdateTime FROM(...)as tbl2 ";

CmdStrBlm = "SELECT dbname, Version, UpdateTime FROM (...)as tbl1 ";

CmdStrPay = "SELECT dbname, Version, UpdateTime FROM(...)as tbl3 ";

CmdStrTran = "SELECT dbname, Version, UpdateTime FROM(...)as tbl4";

DataSet ds = new DataSet();

ds.Tables.Add(GetDataFromDatabase(GetConnectionString(conStringBlm), CmdStrBlm));
ds.Tables.Add(GetDataFromDatabase(GetConnectionString(conStringFg), CmdStrFg));
ds.Tables.Add(GetDataFromDatabase(GetConnectionString(conStringPay), CmdStrPay));
ds.Tables.Add(GetDataFromDatabase(GetConnectionString(conStringTrans), CmdStrTran));

DataTable dtAll = ds.Tables[0].Copy();

for (var i = 1; i < ds.Tables.Count; i++) // this did the trick for 
{                                         // for me with WinForms
    dtAll.Merge(ds.Tables[i]);
}
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = dtAll;

// resize column 3 to fit the window content 

WPF.xaml:

<ListView ItemsSource="{Binding DbVersions}" DockPanel.Dock="Top">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
            <GridViewColumn Header="Version" DisplayMemberBinding="{Binding Version}" Width="60"/>
            <GridViewColumn Header="Last Updated" DisplayMemberBinding="{Binding LastUpdated}" Width="140"/>
        </GridView>
    </ListView.View>
</ListView>

I was trying to use ObservableCollection with class object but not got far. Any help will be much appreciated.

1

There are 1 answers

3
Olaru Mircea On

Simple example:

<Window x:Class="StackSimpleSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView ItemsSource="{Binding persons}">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
            </GridView>
        </ListView.View>
    </ListView>
</Grid>

You have your ListView bounded to persons which is defined in code behind like this:

public partial class MainWindow : Window
{
    public ObservableCollection<Person> persons { get; set; }

    public MainWindow()
    {
        InitializeComponent();
        persons = new ObservableCollection<Person>();
        persons.Add(new Person() { Name = "Person1" });
        persons.Add(new Person() { Name = "Person2" });
        persons.Add(new Person() { Name = "Person3" });
        persons.Add(new Person() { Name = "Person4" });
        this.DataContext = this;
    }
}

And this is the Person class:

public class Person : INotifyPropertyChanged
{
    private string _Name;

    public string Name
    {
        get { return _Name; }
        set
        {
            _Name = value;
            PropertyChanged(this, new PropertyChangedEventArgs("Name"));
        }
    }


    public event PropertyChangedEventHandler PropertyChanged = delegate { };
}

So you have to use that ObservableCollection<Person> instead of creating a DataTable with columns and rows as the Source of the ListView.

Some hints.. ObservableCollection will notify the View when items are added or removed and that INotifyPropertyChanged interface with its PropertyChanged event will notify the GUI when some properties of the items existing in the collection are changed.