I have a grid wrapped in a user control. I need to pass the datasource of the grid through the control.
// My Pass-Through declaration
public object DataSource
{
get { return internalGrid.DataSource; }
set ( internalGrid.DataSource = value; }
}
So far, that's the easy part. The datasource of the grid is a plain Object. The pass-through Datasource is also a plain Object.
When I drop a datagrid directly on my form, I can set datasource by selecting one of my binding source objects on my form. However, when I include my custom control, the pass-through datasource is grayed out. I can't select the binding sources.
I'm certain that I am simply missing a property attribute, but I don't know which one(s). Any help would be appreciated.
Related
I am implementing MVC in a WinForms Application. In the view there is a combobox control. I have declare a property called SheetLoader with getter and setter:
public BindingSource SheetLoader
{
get { return (BindingSource)comboBox_workSheetList.DataSource; }
set { this.comboBox_workSheetList.DataSource = (BindingSource)value; }
}
In controller I want to access setter above and bind the BindingSource to the combobox.
view.SheetLoader = _bindingSource;
But this way is not working. The combobox will not assign any item.
I have debugged it, However the value gets data.
Please help me to bind data from controller to View -> Control.
Ensure you set the DisplayMember and ValueMember of your combobox.
I have a custom UserControl that contains several child controls, amongst which is a DataGridView. I don't want to EnableDesignMode for any of the child controls, but instead have exposed and serialized their properties as needed. I'm stuck on DataGridView's DataSource property.
Do I need to make a custom UITypeEditor and use reflection to find all the BindingSource objects on the parent form for selection, or can I somehow invoke the built-in editor of this type? What type is the editor invoked when changing DataGridView's DataSource?
EDIT: Actually, the suggestion from Oliver did not quite work out. I did get the list of bindable objects in the property grid when I select my UserControl and after I chose a binding source, columns of bound dataset appeared on the grid, but columns of datagridview are not serialized to designer.cs after editing the Columns collection. However, if I build a custom ParentControlDesigner and EnableDesignMode for this datagridview, I can set the binding via it's DesignerVerb, and then the Columns collection is serialized after editing.
I exposed datagridview's Columns and DataSource properties in this way
[Editor(typeof(CollectionEditor), typeof(UITypeEditor))]
[Category("Grid")]
//[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public DataGridViewColumnCollection Columns
{
get { return dgvListaBaza.Columns; }
}
[AttributeProvider(typeof(IListSource))]
[Browsable(true)]
[Category("Grid")]
public object DataSource
{
get { return dgvList.DataSource; }
set { dgvList.DataSource = value; }
}
What is the difference between the way DataSource is set when I click on the control's native designerverb and the one through exposed property? Both show the columns of the bindingSource in the grid after i choose a binding, but Columns don't get serialized in the latter case, as if there is something else I need to set when setting the DataSource.
Also, DesignerSerializationVisibility attribute on the exposed Columns makes no difference, and the column Names in the CollectionEditor are different depending on the way I set the DataSource (If it's set through native designerverb, then they are named SomeColumnDataGridViewTextBoxColumn, and if it's set through the property, then the Name property of each column is empty).
Take a look at DataSource for User Control.
In an assembly I created a class like the following:
[DataObject(true)]
public class A
{
public int Foo{get;set;}
[DataObjectMethod[DataObjectMethodType.Select)]
public static List<A> GetAllA(string ConnectionString)
{
// return filled List<A>
}
}
Now I want to display this List with a Gridcontrol under Winforms. I though of a DataGrid.
Though I'm coming from ASP.net I'd first think of
this.dataGridView1.DataSource = A.GetAllA(ConnectionString)
Works, but I'd prefer a better databinding with BindingSources. (Because I've always heard that thats the way to go)
I managed to drop a BindingSource onto the form and set the DataSource property to class A.
But where can I set the SelectMethod and its parameters? If I set DataSource property of the dataGridView to the BindingSource, it will only display an empty line.
Is this the right way to go? Will it only require some additional clicks in the wizard, or do I need to read tons of documentation to get this working?
Edit: Is there even a way to achieve automatically binding to my select method? Or does the BindingSource only supports mapping the columns, but not actually binding the data, meaning I'm required to set the DataSource property nevertheless?
You need to create a DataSource. Click "Data" menu and select "Add New DataSource..."
Connecting to Data in Visual Studio Overview
http://msdn.microsoft.com/en-us/library/wxt2cwcc(VS.80).aspx
To connect your application to data in
a database, Web service, or object,
run the Data Source Configuration
Wizard
by selecting Add New Data Source from
the Data Sources
Window.
Public Class A
Private _field As String
Public Property Field() As String
Get
Return _field
End Get
Set(ByVal value As String)
_field = value
End Set
End Property
End Class
Public Class AListing
Inherits List(Of A)
End Class
Use AListing as the object when adding a data source. Good for grid views or detail forms that provide navigation. It is up to you to populate it.
Use A as the object when adding a data source. Good for a dialog when you only need to bind to one instance. It is up to you to populate it.
A DataSource just helps the designer configure data binding. You still have to fill the objects. If you do not care about designer support, calling as you do is fine. Using a BindingSource just allows you to use an object like a "data table". Using your example, if I use a BindingSource, I could handle the CurrentChanged event for any additional processing.
this.dataGridView1.DataSource = A.GetAllA(ConnectionString);
//-or-
this.bindingSource1.DataSource = A.GetAllA(ConnectionString);
Have class A retrieve the connection string from the configuration file rather than as a parameter on the GetAllA method. Once your method has no parameters it should be possible to select it in the wizard.
I have a usercontrol that contains a datalist, and I want to set the datasource of the datalist to different things depending on what page the usercontrol is on.
So, I think what I need to do is expose a public property of the datalist that will get the datasource and set it, like so:
public datasource UserDataSource
{
get { return DataList1.DataSource; }
set { DataList1.DataSource = value; }
}
but the above obviously doesn't work. I'd then call it like this:
MyUserControl.UserDataSource = datasourcename;
and then somehow databind the datalist inside the usercontrol.
Obviously I'm kind of out of my element here, but hopefully I can get this working. Thanks for any help.
You need to use find control method to find your datalist first and then assign datasource like...
DataList dl = (DataList)yourLoadedusercontrol.FindControl("yourDatalist");
dl.DataSource = yourdatasource;
I know you have already accepted an answer, but I feel I must add my thoughts:
Your original idea was correct - you just needed to call the databind method of your datalist after setting the datasource. I truly do not feel that doing the above mentioned method is the best way. You should really just have a method or writeonly property (like you do) that takes a possible IList or IEnumerable of your custom object and binds it directly to your datalist. Your page or control that contains this user control should not be aware of your type of data control. If you change it from a Datalist to a Repeater or a GridView, you have to change it everywhere you bind to your user control.
Example:
IList<CustomClass> results = new List<CustomClass>(); //you would load your collection from your database
this.myUserControl.LoadData(results);
In your user control:
public void LoadData(IList<CustomClass> data){
this.datalist1.datasource = data;
this.datalist1.databind();
}
I'm creating a capture form on the fly based on a set of metadata held in a EAV type schema.
My trouble is in load the data back to the control, and in particular a winforms combobox.
Also using Entity Framework for the data that is bound to the control.
Check is control exist, else create. for each mapped property set their values.
i.e. Datasource, DisplayMember, ValueMember, etc...
Load value is exists to SelectedValue property? this is where is fails?
On inspection of the object it seems as if none of the previous values including the datasource has been loaded yet? But the combobox does show the values once rendered?
Here are some snippets of the code.
Type oType = Type.GetType("System.Windows.Forms.ComboBox");
if (oControlObject == null)
{
oControlObject = (Control)Activator.CreateInstance(oType);
oControlObject.Tag = item;
oControlObject.CreateControl();
}
...Loop to set Datasource, DisplayMember & ValueMember ...
if (property.IsReadProperty.Value && value != null)
{
PropertyInfo propSet = oType.GetProperty(property.PropertyName); //PropertyName here is "SelectedValue"
propSet.SetValue(oControlObject, value.Value, null);
}
Got it working. The problem is that the control is not initialized until it is rendered on the form, thus no items collection, even though the datasource is set.
Built up the dynamic form first and then populated the save values by iterating through the controls again... not elegant but it works, until i have another solution.