So the data is loaded properly when I use this method in the Main Window Constructor:
public void Load_Dropdown(configuration con)
{
bindinglist = new BindingList<ListCollection.ListsList>(Get.ListCollection(con).List);
BindingSource bSource = new BindingSource {DataSource = bindinglist};
sharepointListSelect.DataSource = bSource;
sharepointListSelect.DisplayMember = "Title";
sharepointListSelect.ValueMember = "ID";
}
And this works fine, but when I try to call a similar method to update the options at a later time, nothing happens- as in the options in the drop down do not change.
The method I call to update it looks like this:
public bool Reload_Dropdown(configuration con)
{
bindinglist = new BindingList<ListCollection.ListsList>(Get.ListCollection(con).List);
BindingSource bSource = new BindingSource { DataSource = bindinglist };
sharepointListSelect.DataSource = bSource;
sharepointListSelect.DisplayMember = "Title";
sharepointListSelect.ValueMember = "ID";
//There is other logic here, but i left it out as it isn't relevant
return true;
}
Btw, the binding list object is initialized in the class as:
private BindingList<ListCollection.ListsList> bindinglist;
I know, right now I can reuse the first method- but I split up the declaration to debug why it is failing the update in the first place.
I am stupid- So the issue isn't with either method, but how I was calling the method. You cannot call a method from another form if it isn't static. Huge oversight on my part- a bit too accustomed to MVC I suppose.
This solution will work fine, so long as you call it from within the same method. I opted to just have a button that will refresh the dropdown.
Related
I've created a custom user control with a grid. I'd like to bind this grid once, and use it over and over again in my app. If I put the binding within the control, the data is retrieved as many times as I use the control. How do I bind it only once??
public ClientLookUp()
{
InitializeComponent();
vw_clientsTableAdapter.Fill(dsclientlkup.vw_clients); //This occurs as many times as I have the user control, instead of just once.
}
Well anything you put in the constructor will be executed every time you construct the object!
What about providing an Initialize method that you can call whenever you need to reload the data??
If you want to load the data only once, then load it either into a static variable or a separate class that is referenced by the control.
If you really want to use the same single grid in your control over and over, you could create a single, static grid, and have your ClientLookUp constructor add it to the right place—Panel, or whatever—whenever a new one is created.
Before you go do this road however, ask yourself if this is really what you want to do. Having the same identical grid existing in many places may cause you problems down the road. If you want to support in-grid editing, you'll find that changing one value changes the identical value in all your other grids..
EDIT
I tried getting the below code to work, but I'm not sure this approach will be possible. It seems as though the minute you try to attach the same UI element into more than one place, it gets moved out of the last place you put it; it doesn't look like you can have the same grid being in more than one place at once. This makes sense when you think about it.
Here's the code I tried. Maybe it will be of some use to you.
public UserControl1()
{
InitializeComponent();
this.Controls.Add(myStaticGridView);
myStaticGridView.Dock = DockStyle.Fill;
}
static DataGridView _staticGrid;
public DataGridView myStaticGridView
{
get
{
if (_staticGrid != null)
return _staticGrid;
_staticGrid = new DataGridView();
_staticGrid.Columns.Add("A", "A");
_staticGrid.Columns.Add("B", "B");
_staticGrid.Columns.Add("C", "C");
_staticGrid.Columns[0].DataPropertyName = "A";
_staticGrid.Columns[1].DataPropertyName = "B";
_staticGrid.Columns[2].DataPropertyName = "C";
_staticGrid.DataSource = new[] {
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
};
return _staticGrid;
}
}
And then loading the control like this:
private void button1_Click(object sender, EventArgs e)
{
flowLayoutPanel1.Controls.Add(new UserControl1());
}
I am using WinForms C#
Is there any way to get following behavior:
bind List to CheckedListBox
When I add elements to list CheckedList box refereshes
When I change CheckedListBox the list changes
I tried to do the following:
Constructor code:
checkedlistBox1.DataSource = a;
checkedlistBox1.DisplayMember = "Name";
checkedlistBox1.ValueMember = "Name";
Field:
List<Binder> a = new List<Binder> { new Binder { Name = "A" } };
On button1 click:
private void butto1_Click(object sender, EventArgs e)
{
a.Add(new Binder{Name = "B"});
checkedListBox1.Invalidate();
checkedListBox1.Update();
}
But the view does not update .
Thank You.
Change this line:
List<Binder> a = new List<Binder> { new Binder { Name = "A" } };
to this:
BindingList<Binder> a = new BindingList<Binder> { new Binder { Name = "A" } };
It will just work without any other changes.
The key is that BindingList<T> implements IBindingList, which will notify the control when the list changes. This allows the CheckedListBox control to update its state. This is two-way data binding.
Also, you could change these two lines:
checkedListBox1.Invalidate();
checkedListBox1.Update();
to this (more readable and essentially does the same thing):
checkedListBox1.Refresh();
Two things you may wish to look at:
Use a BindingList
Add a BindableAttribute to your Name property
Does your List<Bender> need to be some kind of observable collection, like ObservableCollection<Bender> instead?
The proper way of binding a checked listbox is:
List<YourType> data = new List<YourType>();
checkedListBox1.DataSource = new BindingList<YourType>(data);
checkedListBox1.DisplayMember = nameof(YourType.Name);
checkedListBox1.ValueMember = nameof(YourType.ID);
Note to self.
The issue i have every time binding it is that the properties DataSource, DisplayMember and ValueMember are not suggested by intellisense and i get confused.
I have an object Proposal which has a property called CurrentAgency of Agency which in turn has AgencyID, Name, etc...something like this:
Proposal
CurrentAgency
AgencyID
Name
Address
etc...
In my UI, I have a combobox that lists all available Agencies. I have bound it like this:
private BindingSource bndProposal = new BindingSource();
bndProposal.DataSource = typeof(Model.Proposal);
lkpAgency.DataBindings.Add("EditValue", bndProposal, "CurrentAgency.AgencyID");
lkpAgency.Properties.DataSource = FusionLookups.LookupAgencies;
lkpAgency.Properties.DisplayMember = "Name";
lkpAgency.Properties.ValueMember = "ID";
And this works well enough. If the user changes the agency, Proposal.CurrentAgency.AgencyID is automatically updated. However, the problem is that the rest of the properties of the CurrentAgency object are not updated.
What are some of the patterns that are used to handle this kind of situation while not gunking up the code with junk? Do I handing the Format event on the Binding object? Any ideas for clean implementation are welcome.
Have you tried the following?
private BindingSource bndProposal = new BindingSource();
bndProposal.DataSource = typeof(Model.Proposal);
lkpAgency.DataBindings.Add("EditValue", bndProposal, "CurrentAgency");
lkpAgency.Properties.DataSource = FusionLookups.LookupAgencies;
lkpAgency.Properties.DisplayMember = "Name";
lkpAgency.Properties.ValueMember = null;
My binding is set up as this:
_selectXAxisUnitViewModelBindingSource = new BindingSource();
_selectXAxisUnitViewModelBindingSource.DataSource = typeof(SelectXAxisUnitViewModel);
_selectedUnitComboBoxBindingSource = new BindingSource();
_selectedUnitComboBoxBindingSource.DataSource = _selectXAxisUnitViewModelBindingSource;
_selectedUnitComboBoxBindingSource.DataMember = "AvailableUnits";
_selectedUnitComboBox.ComboBox.DataSource = _selectedUnitComboBoxBindingSource;
_selectedUnitComboBox.ComboBox.DisplayMember = String.Empty;
_selectedUnitComboBox.ComboBox.ValueMember = String.Empty;
_selectedUnitComboBox.ComboBox.DataBindings.Add("SelectedItem",
_selectXAxisUnitViewModelBindingSource,
"SelectedUnit", true, DataSourceUpdateMode.OnPropertyChanged);
// this is a bug in the .Net framework: http://connect.microsoft.com/VisualStudio/feedback/details/473777/toolstripcombobox-nested-on-toolstripdropdownbutton-not-getting-bindingcontext
_selectedUnitComboBox.ComboBox.BindingContext = this.BindingContext;
The property "AvailableUnits" is a collection of strings and the "SelectedUnit" is a string-property. Now the dropdown list is populated as expected, but when I select and item in the list, the change is not propagated to the binding source. Any idea what I am doing wrong?
Update:
I Created a little test project and this problem occurs when I add a ToolStripComboBox as a subitem of another ToolStripItem. If I add the ToolStripItem directly to the MenuStrip everything works fine. The BindingContext is not assigned to the ToolStripComboBox when added as a sub item (see my code-comment) and my fix doesn't seem to do whats necessary to get this to work.
Can you change
_selectXAxisUnitViewModelBindingSource.DataSource = typeof(SelectXAxisUnitViewModel);
To
_selectXAxisUnitViewModelBindingSource.DataSource = new SelectXAxisUnitViewModel();
I'm binding to a dropdown. It works on the initial load. On subsequent loads (postbacks) it doesn't refresh the items in the dropdown.
using (DataView dv = dtProductGroup.DefaultView)
{
dv.ApplyDefaultSort = false;
dv.Sort = "KVIGroupName ASC";
ddlGroup.ClearSelection();
ddlGroup.Items.Clear();
string strAll = Localization.GetResourceValue("_strddlStatusLBAll");
ddlGroup.DataValueField = "KVIGroupId";
ddlGroup.DataTextField = "KVIGroupName";
ddlGroup.DataSource = dv;
ddlGroup.DataBind();
ListItem item = new ListItem(strAll, "0");
ddlGroup.Items.Insert(0, item);
}
I've confirmed that on the postbacks the data is being bound to the dropdown and items are successfully added. But when the page renders the dropdown doesn't have any of the new values.
I see two possibilities: The control isn't rendering the new values or the values are being cleared. I'm at a loss of where to look for possible problems.
Edit
I discovered the problem. The dropdownlist was embedded in an Conditional UpdatePanel. Simply calling "UpdatePanel.Update();" solved the problem.
Upon Postback the viewstate is being reapplied + you said you're trying to load values again. I'd suggest letting viewstate carry all the weight on postback. Only load the values when the page is first hit by adding if (! IsPostBack) like so
using (DataView dv = dtProductGroup.DefaultView)
{
if (! IsPostBack) {
dv.ApplyDefaultSort = false;
dv.Sort = "KVIGroupName ASC";
ddlGroup.ClearSelection();
ddlGroup.Items.Clear();
string strAll = Localization.GetResourceValue("_strddlStatusLBAll");
ddlGroup.DataValueField = "KVIGroupId";
ddlGroup.DataTextField = "KVIGroupName";
ddlGroup.DataSource = dv;
ddlGroup.DataBind();
ListItem item = new ListItem(strAll, "0");
ddlGroup.Items.Insert(0, item);
}
}
Edit:
Also, your syntax ensures the DataView object referenced by dv is Disposed of when the code block exits. My second guess is this causes a side-effect that causes the problem.
using (DataView dv = dtProductGroup.DefaultView)
{
Instead leave out the using and write a regular declaratoin like the following (The DataView is going to be Disposed along with everything else when the page is done rendering so there's not really any need to do it yourself).
DataView dv = dtProductGroup.DefaultView;
See the MSDN documentation about 'using' and IDisposable for detailed info.