This is the section of the form I am working on:
The following code links the BindingNavigator to the dataset using a bindingSource. Can I use this binding source to hook up the two text boxes to the data?
Do I simply need to use a property of the textboxes or is this more involved?
i.e when the form loads the first record's fields "Work Phrase" and "Description" will be displayed and when I scroll using the navigator the values in these boxes will change accordingly.
public partial class uxRevisionHelperForm : Form
{
public SqlCeConnection conn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["WindFormAppRevisionHelper.Properties.Settings.DefinitionsDBConnectionString"].ConnectionString);
BindingSource definitionsBindingSource = new BindingSource();
public uxRevisionHelperForm()
{
InitializeComponent();
uxDescriptionTextBox.AutoSize = true;
this.hookUpBindingNavigator();
}
public void hookUpBindingNavigator()
{
SqlCeDataAdapter da = new SqlCeDataAdapter(new SqlCeCommand("Select * From tb_Definitions",conn));
DataSet ds = new DataSet("Helper");
ds.Tables.Add("DefinitionsTable");
da.Fill(ds.Tables["DefinitionsTable"]);
// Assign the BindingSource.
this.uxBindingNavigator.BindingSource = this.definitionsBindingSource;
this.definitionsBindingSource.DataSource = ds.Tables["DefinitionsTable"];
}
Try using the DataBinding collection of the textboxes.
Something like this:
uxDescriptionTextBox.DataBindings.Add("Text",
definitionsBindingSource,
fieldInTable);
Have added the full source code (highlighting exactly your requirement) here - http://sdrv.ms/NyXHdu. Download > Open the solution in VS2010 > Hit F5
[Update]
Double click on Form.cs designer and observe the productListBindingSource. It bound to a custom object - The ProductList class
Then see the properties of the TextBoxes & ComboBox and observe the DataBindings > Text property. They are bound to the productListBindingSource's individual item. See Image below.
Courtsey - http://www.apress.com/9781590594391/ [Chapter 8]
Related
I have tow form,ListFrom, and DetailForm
In the ListForm I have a devexpress grid and some button(add, delete, edit)
In the DetailForm I have some textboxes and some button(save,delete,next,previous)
well I have to senario
1 - I open the ListForm and I click on a product to modify it a got the DetailForm opened, I make some modification and I save,then i should have my grid in the ListForm refreshed with the new value.for this I have this code
In the ListFrom
FrmProduit frm = new FrmProduit(monProduit.Id) { MdiParent = this.MdiParent};
frm.updateDataInGridView += new System.Action(refereshGridView);
frm.Show();
in the detailform
if (updateDataInGridView != null)
updateDataInGridView();
well in this scenario everything is OK
second scenario
If I open the detailFrom,and after that I open the listForm, I make some change in the detailFrom and I click save updateDataInGridView in this case is null and then the grid is not refreshed
anyone have suggestion?
I would create a shared BindingSource that both forms would use to show data. If any item is changed in BindingSource it takes care to notify all controls bind to it and so it would refresh grid automatically.
Second approach is to make refereshGridView method public and in DetailForm on save click do this:
var lists = Application.OpenForms.OfType<Form>().Where(x => x.GetType() == typeof(ListFrom));
foreach (var listform in lists)
{
listform.refereshGridView();
}
I did not use FirstOrDefault as maybe there is more than one listform opened.
EDIT about Binding Source
Here is quite good tutorial so please take a look.
Below is a fast-written far from best example of stretch I did:
internal static class DataSources
{
private static BindingSource bs;
public static BindingSource CerateDataSource(List<object> yourObjects)
{
bs = new BindingSource();
bs.DataSource = yourObjects;
}
public static BindingSource GetDataSource()
{
return bs;
}
public static void Reset()
{
bs.ResetBindings(false);
}
}
and then in your listview
dataGridView1.DataSource = DataSources.GetData();
and in detailsview where you are editing one of the objects from BindingSource on save you would have to call: DataSources.Reset();. This is just a markup, but hopefully you get the idea :).
You must always be sure you are referring to the current instance of detailform, thus declare on your listForm
detailform obj = (detailform)Application.OpenForms["detailform"];
And every time you call detailform from listForm do it by obj e.g:
obj.Show()
I have developed a form in c# which is called inside a console application.
Below is how i have called the form inside the console.
Application.Run(new Form1(display_list));
displaylist is a list of struct
List , form_columns is a struct consisting of 3 string values which needs to be displayed side by side in a datagrid.
Below is the constructor of the form
public Form1(List<form_columns> disp)
{
InitializeComponent();
BindingSource source = new BindingSource();
source.DataSource = disp;
dataGridView1.AutoGenerateColumns = true;
dataGridView1.DataSource = source;
}
But when the program is run , the datagridview is empty. it is not showing any data .
What mistake am i making?????
Try to bind the list using BindingList
BindingList<form_columns> bl = new BindingList<form_columns>(disp);
BindingSource source = new BindingSource(bl, null);
//source.DataSource = disp;
I'm creating a form that will act as a master-detail editor. I have 2 controls on this form. One is basically a list of mater items and the other control is the details of the item. I'm trying to use a the same BindingSource object in both controls so that when a change is made on the master control, the detail control will get updated.
In my form I have:
EmployerCollection employerCollection = new EmployerCollection();
employerCollection.GetMulti(null, 0, new SortExpression(EmployerFields.Name | SortOperator.Ascending));
bsEmployers.DataSource = employerCollection;
masterControl.Init(bsEmployers);
detailControl.Init(bsEmpoyers);
In my masterControl I have:
public void Init(BindingSource bs)
{
bsEmployers = bs;
}
However for the life of me I can't get my master control to display the data in the binding source when I pass it in this way.
I can get binding to work only if I remove the bsEmployers = bs line and move the other logic as follows:
public void Init(BindingSource bs)
{
EmployerCollection employerCollection = new EmployerCollection();
employerCollection.GetMulti(null, 0, new SortExpression(EmployerFields.Name | SortOperator.Ascending));
bsEmployers.DataSource = employerCollection;
}
Does anyone have any idea what I can't pass the BindingSource object in to share it? I tried calling RefreshBindings in my control, but it did not seem to have any effect.
Thanks.
I don't think that the BindingSource was intended to be used that way. I would recommend passing the EmployerCollection value to the Init method and have each control create its own BindingSource using the EmployerCollection.
I'm trying to bind a collection to a DataGridView. As it turns out it's impossible for the user to edit anything in this DataGridView although EditMode is set to EditOnKeystrokeOrF2.
Here is the simplified code:
public Supplies()
{
InitializeComponent();
List<string> l = new <string>();
l.Add("hello");
this.SuppliesDataGridView.DataSource = l;
}
It also doesn't work when I change the collection type to SortableBindingList, Dictionary or even use a BindingSource.
What can be wrong here?
For me the following method works as expected:
Open your form (usercontrol, etc.) with the designer
Add a BindingSource to your form
Select the BindingSource in your form and open the properties page
Select the DataSource property and click on the down arrow
Click on Add project data source
Select Object
Select the object type you wish to handle
This should be the type that will be handled by your collection, not the CustomCollection itself!
Show the available data sources by selecting from the MenuBar Data - Show Data Sources
Drag and Drop your ItemType from the DatasSources on your form
Go into the code of your form and bind your CustomCollection to the BindingSource
var cc = new CustomCollection();
bindingSource1.DataSource = cc;
Remarks:
The DataGridView is just the last part in your chain to (dis)allow changing, adding and removing objects from your list (or CustomCollection). There is also a property AllowNew within the BindingSource and the ICollection interface has a property IsReadOnly which must be set to false to allow editing. Last but not least, the properties of your class within the collection must have a public setter method to allow changing of a value.
Try this:
public class CustomCollection { public string Value { get; set; } }
public Supplies()
{
InitializeComponent();
List<CustomCollection> l = new List<CustomCollection> { new CustomCollection { Value = "hello" } };
this.SuppliesDataGridView.DataSource = l;
}
Once you've set the DataSource property you'll then want to fire off the DataBind() method.
this.SuppliesDataGridView.DataSource = l;
this.SuppliesDataGridView.DataBind();
UPDATE:
As you rightly pointed out in the comments, the DataBind() method doesn't exist for this control.
This link might provide some helpful information: http://msdn.microsoft.com/en-us/library/fbk67b6z%28v=VS.90%29.aspx
I've got the following code which I think ought to be binding a DataTable to a DataGridView, but the DataGridView shows up empty. The DataTable definately has rows, so I assume that I am binding the DataSource incorrectly some how. Does anyone see what is wrong with this:
DataBase db = new DataBase(re.OutputDir+"\\Matches.db");
MatchDBReader reader = new MatchDBReader(db.NewConnection());
BindingSource bindingSource = new BindingSource();
bindingSource.DataSource = reader.GetDataTable();
this.dataGridView1.DataSource = bindingSource.DataSource;
The first line simply gets a handle to the DB that I'm pulling data from.
The next line is a provides a class for reading from that same db - in particular it exposes the GetDataTable method with returns the data table that I intend to put into the DataGridView.
The next line is uninteresting...
The 4th line attempts to grab the DataTable - QuickWatch indicates that this is working...
The final line is where I assume i've screwed up...my understanding is that this binds the DataTable to the DataGridView GUI, but nothing shows up.
Any thoughts?
Try binding the DataGridView directly to the BindingSource, and not the BindingSource's DataSource:
this.dataGridView1.DataSource = bindingSource;
You need to attach your BindingSource to your grid, before you get the data table.
Try switching the last two lines of code:
DataBase db = new DataBase(re.OutputDir+"\\Matches.db");
MatchDBReader reader = new MatchDBReader(db.NewConnection());
BindingSource bindingSource = new BindingSource();
this.dataGridView1.DataSource = bindingSource.DataSource;
bindingSource.DataSource = reader.GetDataTable();
Along with above solutions also fix the "bindingSource" datamember property. like:
bindingSource.DataMember = yourDataSet.DataTable;
I had the same problem with sql database and datagrid view. After a great deal of trouble I found out that I've forgot to set dataMember property of my binding source.
best of luck.
None of this worked for me, though it all seemed like good advice. What I ended up doing was the biggest, worst hack on earth. What I was hoping to accomplish was simply to load a DB table from a SQLite db and present it (read only, with sortable columns) in the DataGridView. The actual DB would be programmatically specified at runtime. I defined the DataSet by adding a DataGridView to the form and used the Wizards to statically define the DB connection string. Then I went into the Settings.Designer.cs file and added a set accessor to the DB Connection string property:
namespace FormatDetector.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "9.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
[global::System.Configuration.DefaultSettingValueAttribute("data source=E:\\workspace\\Test\\Matches.db;useutf16encoding=True")]
public string MatchesConnectionString {
get {
return ((string)(this["MatchesConnectionString"]));
}
set
{
(this["MatchesConnectionString"]) = value;
}
}
}
}
This is a klugey hack, but it works. Suggestions about how to clean this mess up are more than welcome.
brian
DataGridView takes a DataTable as a basis. The DataTable Columns save their Type as a property.
If this type is an Interface all you would see are empty cells.