1

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.

4
  • So what type of collection is DbVersions right now? Commented Jun 17, 2015 at 11:29
  • I was trying to go with this approach public ObservableCollection<DataTable> _observableCollection = new ObservableCollection<DataTable>() as in link I posted. Not sure if this is even right. Commented Jun 17, 2015 at 11:35
  • You need to use ObservableCollection<YourCustomClass>. Your class implement INotifyPropertyChanged interface and trigger an event on its properties set branch. I will try to add a simple example. Commented Jun 17, 2015 at 11:39
  • Let me know if you need a binding to DataTable example too. Commented Jun 17, 2015 at 12:04

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Ok I don't get it. So where my DataSet will need to be used? I had INotifyProprtyChanged interface implemented already but had no clue how to bind this together with what I have. What will be persons.Add(new Person() { Name = "Person1" }); in my case?
@Jakubee With details from your Database table you have to create Models, i mean c# classes with their information. Like that Person class. It was just an example. You will have to implement your own data access layer and store what's needed.
I have no idea how to do this ;(( lost entire day on this already. So all the SQL queries should stay and would be used in Model class? Can you provide me an example of how it might look?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.