Click here to Skip to main content
15,891,567 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more: , +
Hi experts,

let's assume this code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test_DataBinding
{
    public partial class Form1 : Form
    {
        private FooContainer _foos = new FooContainer();

        public Form1()
        {
            InitializeComponent(); // Including Multiselect = false

            foreach (Foo foo in _foos.Items)
            {
                int rowIndex = dgvFoo.Rows.Add();
                dgvFoo.Rows[rowIndex].Cells["ObjectName"].Value = foo.Name;
                dgvFoo.Rows[rowIndex].Tag = foo;
            }

            //dgvFoo.DataBindings.Add(dgvFoo.selectedrow
        }


        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
    }


    public class FooContainer
    {
        private List<foo> _fooList = new List<foo>();
        private Foo _selected = null;


        public FooContainer()
        {
            _fooList.Add(new Foo("First"));
            _fooList.Add(new Foo("Second"));
            _fooList.Add(new Foo("Third"));
        }


        public List<foo> Items
        {
            get { return (_fooList); }
        }


        public Foo SelectedItem
        {
            get { return (_selected); }
            set { _selected = value; }
        }
    }


    public class Foo
    {
        private string _name = string.Empty;


        public Foo(string name)
        {
            _name = name;
        }


        public string Name
        {
            get { return (_name); }
        }


        public override string ToString()
        {
            string name = _name;
            if(name==string.Empty)
                name = "NoName";

            return (name + "(" + this.GetType().ToString() + ")");
        }
    }
}
</foo></foo></foo>
What I'm trying to do in the line that is commented out is to databind the properties FooContainer.SelectedItem and DataGridView.SelectedRows.

The user should be able to change the selected item in FooContainer by changing the selection in the DataGridView.
And a programatical change in FooContainer.SelectedItem shall be shown in DataGridView.

FooContainer.SelectedItem is of type Foo.
DataGridView.SelectedRows is a list of DataGridViewRows with Foos attached as Tags.
How can thy be databound?

Thanks in advance,


luker
Posted

1 solution

Hi
I'm focusing on "The user should be able to change the selected item in FooContainer by changing the selection in the DataGridView."

The following solution lets the user select items by clicking the cell, and the following event sets the according item in the bound data collection to the SelectedItem in your FooContainer-class.

Your should ask you self if the FooContainer-class really is needed.

Please remember to vote and comment!

C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Test_DataBinding
{
    public partial class Form1 : Form
    {
        private FooContainer _foos = new FooContainer();

        public Form1()
        {
            InitializeComponent(); // Including Multiselect = false

            /*foreach (Foo foo in _foos.Items)
            {
                int rowIndex = dgvFoo.Rows.Add();
                dgvFoo.Rows[rowIndex].Cells["ObjectName"].Value = foo.Name;
                dgvFoo.Rows[rowIndex].Tag = foo;
            }*/

            //dgvFoo.DataBindings.Add(dgvFoo.selectedrow

            dgvFoo.DataSource = _foos.Items;
            dgvFoo.CellClick += new DataGridViewCellEventHandler(dgvFoo_CellClick);
        }


        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }
    }

    void dgvFoo_CellClick(object sender, EventArgs e)
    {
        foreach (DataGridViewRow row in dgvFoo.SelectedRows)
        {
            Foo myFoo = row.DataBoundItem as Foo;
            if (myFoo != null)
            {
                // Assuming only one selected
                _foos.SelectedItem = myFoo;
            }
        }
    }


    public class FooContainer
    {
        private BindingList<foo> _fooList = new BindingList<foo>();
        private Foo _selected = null;


        public FooContainer()
        {
            _fooList.Add(new Foo("First"));
            _fooList.Add(new Foo("Second"));
            _fooList.Add(new Foo("Third"));
        }


        public BindingList<foo> Items
        {
            get { return (_fooList); }
        }


        public Foo SelectedItem
        {
            get { return (_selected); }
            set { _selected = value; }
        }
    }


    public class Foo
    {
        private string _name = string.Empty;


        public Foo(string name)
        {
            _name = name;
        }


        public string Name
        {
            get { return (_name); }
        }


        public override string ToString()
        {
            string name = _name;
            if(name==string.Empty)
                name = "NoName";

            return (name + "(" + this.GetType().ToString() + ")");
        }
    }
}</foo></foo></foo>
 
Share this answer
 
v3
Comments
lukeer 8-Apr-11 8:42am    
> event sets the according item
> in the bound data collection
Of course I thought of the event approach in the first place. But I suspect the reverse way to get necessary at some time in the future. Then, I will have to re-work FooContainer to inform DataGridView of changes.
I was hoping that databinding would do that for me right now.
For the time being, the one-way solution will do just as well.

> _foos.SelectedItem = _foos.Items[e.RowIndex];
Is the item order guaranteed to be fixed?
If not, does the databinding transfer the new item order?

> You should ask yourself if
> the FooContainer-class really is needed.
As you surely can imagine, the FooContainer is a simplification of some real class which is still needed for reasons other than storing the selected item.
Amund Gjersøe 8-Apr-11 9:10am    
Is the item order guaranteed to be fixed?
No. If you implement a sortable BindingList and use that as the data source, you would get a mismatch. A safe way is:
void dgvFoo_CellClick(object sender, EventArgs e)
{
foreach (DataGridViewRow row in dgvFoo.SelectedRows)
{
Foo myFoo = row.DataBoundItem as Foo;
if (myFoo != null)
{
_foos.SelectedItem = myFoo;
}
}
}
Amund Gjersøe 8-Apr-11 9:14am    
I haven't tested this one, but it should work.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900