I've build a base user control, BaseViewControl, it has a dataGridView and a bindingSource on it. Both have protected access modifiers. The dataViewGrids dataSource points to the base forms bindingSource.
Then I created an InheritedUserControl, ApplicationUserView, when prompted I pointed it to my UI assembly. It inherited some other arb UserControl in the same assembly so I manually changed it to inherit my BaseViewControl.
On the ApplicationUserView's bindingSource, I set the dataSource property to my ApplicationUser domain object. The dataGridView then proceeded to populate its columns with the properties in my ApplicationUser domain class in the DesignView, as expected.
Now, in an async callback from my controller object, where the view receives an IList<ApplicationUser>, i set my bindingSource.DataSource = applicationUserList.
I've confirmed that the callback gets called and that the applicationUserList has items in it, but at run time, the grid doesn't show any rows. I suspect it has something to do with the visual inheritance aspect of it all.
I've seen VS create copies of items from inherited forms onto the inheriting form as soon as you try and modify a property of an inherited item before, which has a similar effect, but this is not the case.
Any ideas what I'm doing wrong?
Thanks, HS
Related
In great need help with the strange binding problem with regards to Winform UserControls.
Its like this.
Have a form with a UserControl
UserControl has a System.Windows.Forms.BindingSource control
BindingSource has a DataSource set to an entity POCO type at design time.
UserControl has controls that are bound to properties on the POCO class. An example: CreateDate
No problem in designer of the UserControl itself.
But entering the designer og the Form containing the UserControl, I get a designer error window with the message: "Cannot bind to the property or column CreateDate on the DataSource. Parameter name: dataMember"
In runtime I get the same error, but first when Show is called on the form. Here I can see on the stack trace that it is thrown after a CheckBinding call.
The error occurs no matter if the DataSource on the bindingSource is set or not during the creation (in constructor) or Load event on the form.
I can see that the designer sets my data source like this in the designer file: this.bindingSourceRecipe.DataSource = typeof(Data.Entities.Recipe);
I have tried so many things to solve this problem. It seems very strange as this is a dead simple form/control setup and should be a trivial use of Winforms usercontrols.
If I set the bindingSourceRecipe.DataSource at runtime to a temp. instance just after the InitializeComponent() in the form then no error occure;
InitializeComponent();
ucRecipeBaseControl.Recipe = new Recipe() { Id = 0, CreateDate = DateTime.Now, Name = "" };
So it seems that the Initialization cycle of the form/control somehow clears the binding source knowledge about its DataSource type.
This does of course not happen if a place all the user controls and BindingSource Directly on the form. Then everythings works, and it does not matter if the DataSource ever gets set to an instance of a Data entity.
Seems like a complete mystery to me, should be dead simple, and I'm kind of lost on what to do.
Any help or suggestions are highly appreciated.
BR Peter Meldgaard
Ahhh, got it nailed at last. It was caused by a mix of Winform designer behavior and my code. I was setting the binding controls datasource in a public property setter, so I could save a copy of the entity, to be able to compare the changed and the org. The thing is that when you put a control with a public property on a form, then the designer initializes this property to null inside the designer generated code. I did not know that. So everytime the usercontrol was instantiated, the DataSource got set to null, clearing the typeof(dataentity), albeit loosing the binding information.
Adding a null check in the setter, and only update datasource when value is not null fixed the issue.
I have 2 projects:
Project A which consists of a Usercontrol named BaseUC which consists of a RadPanel and a RadGridView (both have modifier set to public)
Project B which consists of a Usercontrol which inherits from BaseUC
(from the class itself). Project A is included as referenced dll in Project B
Now the situation is so:
Both elements from BaseUC are shown in the DerivedUC.
The RadLabel I can edit without problems (properties) in project B
The GridView has its properties grayed out in project B
If I give GridView events which I implement as virtual in project A and overwrite them in project B I run into the problem that I get an exception as soon as I try to fire the events. Same if I try to manually add events to the gridview in project B.
So my question is twofold there but comes down to the basic question if event handling is possible for visually inheritted RadGridViews:
How can I get the RadGridView to have its properties editable in design view in project B?
How can I handle events there?
That is if these two things are possible at all.
You can expose the child controls contained in your UserControl as a public property, that is creating a public property that returns the child control and not just making the child variable public. This will make the child control available to sink event handlers and set public properties. Note that this breaks one of object orientation rules namely, encapsulation....but rules are meant to be broken for certain cases that fits the requirement :)
I have created a DataSet with multiple tables. I use a few tables on one form, and then 2 other tables on 2 other forms. When I try to do the binding of the data, I cannot figure out how to have all 3 forms refer to the same DataSet object. In the interface (Visual Studio Express 2013) I can select from the Project Data Sources list and get my MainDataSet class and then select whichever table I want. But if I do this, I get a new object. None of the other options seem to allow me to pick an already existing object. I thought I used to see an option to pick my MainDataSet object from somewhere, but I don't currently see that option and even so, it didn't allow me to select a table anyway.
I know I could look closer at the binding code and figure out how to make this work, but since some of that code is in the Designer file, I can't modify it so it seems the best I can do if I do this is replace what it did with new bindings. And it seems like I shouldn't have to do this. There HAS to be a way to do this in the Visual Studio GUI.
You should create a BindingSource in the designer, then set its source to the DataSet in the designer.
You can then change your form's constructor to set the BindingSource's source to a shared DataSet.
Based on SLaks' suggestion, here is what I did.
I dragged a BindingSource onto a form and named it sharedDataSource.
In the Properties of the BindingSource I set the DataSource by selected MyDataSet class under the Project Data Sources heading. I believe this created the DataSource object and bound it to the BindingSource.
In the designer I chose the data source for the the DataGridView objects by selecting sharedDataSource and then the appropriate table under that.
For the DataGridViews in the second form I selected Other Data Sources-->Project Data Sources-->MyDataSet.
I created a constructor for the second form that takes a MyDataSet object as a parameter. In the constructor I set both SomethingOrOtherBindingSource.DataSource and mainDataSet to the paramater. I think the former is required, but the latter may only be required if you refer to it in your code.
When I create the second form (from the first form), I passed in sharedDataSource to the constructor.
So in the designer a data source is bound to the grid and you can use the designer to do whatever you need to (e.g. change column sizes, etc.), but when the program is run, the data source is changed to be the shared one. It seems to work.
I'm currently building an application that utilizes a ComboBox to allow the user to select from a dynamic list of String objects contained within a BindingList object. However, the BindingList is a member of a child class belonging to the main class, which appears to be causing some issues.
When the ComboBox's data source is set initially within the main class via:
this.comboBox.DataSource = this.childClass.dataList;
the contents of the ComboBox appear as expected. However, when the contents of the list changes, the contents of the ComboBox are not updated.
If the BindingList object belongs to the main class, the ComboBox updates without any issues. It would appear that the parent class is not receiving the events that signal that the list has been updated.
Any ideas?
After looking at a similar question I asked (and answered) last year:
Adding/Removing COM Ports from a ComboBox in C#
, it seems I've (re)discovered the solution. The problem was with how the strings were being added to the data source. Because the list was being augmented in another thread, there was an issue with the ComboBox control being updated. By utilizing a delegate and the Invoke() method, the contents of the ComboBox are now updated as expected.
I have a user control that has among other things a label AND a textbox control. With this class, I set the textbox to have its modifier as "public", so when I subclass THIS control, I can get directly to the properties and such of the textbox in each instance where needed. No problem.
Now, the problem. I do the exact same thing but with a dataGridView control (and some others) within a user control. Set ITs modifier to public with intent to derive this user control downstream. Now, I try to derive this control to a NEW control and can't directly touch the dataGridView and add columns, sizing, etc directly.
I tried reproducing the described behavior and was able to do so with the GUI designer in VS 2008 using .Net 3.5. I suspect you are running into the same issue as this problem
That means to get the desired behavior you may need to implement a custom designer. There is even an example designer given by another person answering the question. Please have a look and see if that helps.