Databinding a multiselect ListBox in a FormView control
I have a multiselect ListBox within a FormView. I can't figure out how to setup the databinding for it.
I can populate the listbox fine. If the listbox was a single select I could use saySelectValue='<%#Bind("col")%>'
and that works fine.
Is there something that I can bind to for a multiselect listbox?
I've tried manually DataBinding by handling the DataBinding event of the listbox and setting the selected property on the appropriate items. Unfortunately, there are no items in the listbox during the DataBinding event.
The closest thing I've found is to save the value that determines what items should be selecting during DataBinding and then use that value in the FormViews DataBinding event to select the right items which seems like a hack to me.
Is there a better way?
EDIT:
To clarify what I am currently doing...
I am using the FormViews's ItemCreated event to save the FormView's DataItem. Then in the FormView's DataBound event I find the listbox and manually set the selected items. It doesn't seem right that I have to save the value like this and I assume there 开发者_StackOverflow中文版is a more correct way to do this that I just can't see.
Did you try the ItemDataBound
event?
When I've done this in the past I've set the data source of the listbox, bind it, then iterate through the list of items in the listbox and set the .Selected to true for each item that matches my criteria or values. I'm not sure it's the most efficient, but for the small lists I've dealt with it certainly worked fine.
What I ended up doing was abandoning the ListBox all together and I settled on a TreeView, as it actually served my purposes better.
Before that though I did write this function to select the current items and I called it from Page_PreRender because binding is complete then, and I could get the controls I needed.
protected void SelectCategories()
{
ListBox lb = (ListBox)fvProduct.FindControl("lstCategory");
Product product = (Product)pdc.Products.Where(a => a.Sku == txtSku.Text).FirstOrDefault();
var c = pdc.ProductCategories.Where(b => b.ProductId == product.ProductId);
if (lb != null && lb.Items.Count > 0)
{
foreach (ProductCategory cat in c)
{
foreach (ListItem li in lb.Items)
{
if (cat.CategoryId == Convert.ToInt32(li.Value))
{
li.Selected = true;
}
}
}
}
}
And then when I need to update from the ListBox I called the following code from the FormView.ItemUpdating event.
protected void UpdateCategories()
{
ListBox lb = (ListBox)fvProduct.FindControl("lstCategory");
Product product = (Product)pdc.Products.Where(a => a.Sku == txtSku.Text).FirstOrDefault();
if (lb != null && lb.Items.Count > 0)
{
foreach (ListItem li in lb.Items)
{
ProductCategory pc = new ProductCategory();
pc = (ProductCategory)pdc.ProductCategories.Where(d => d.CategoryId == Convert.ToInt32(li.Value) && d.ProductId == product.ProductId).FirstOrDefault();
if (pc == null)
{
if (li.Selected == true)
{
//note: if li is selected but pc is null then insert new record .
pc = new ProductCategory();
pc.ProductId = product.ProductId;
pc.CategoryId = Convert.ToInt32(li.Value);
pdc.ProductCategories.InsertOnSubmit(pc);
pdc.SubmitChanges();
}
}
else
{
if (li.Selected == false)
{
//note: if li is not selected but pc is not null then remove record.
pdc.ProductCategories.DeleteOnSubmit(pc);
pdc.SubmitChanges();
}
}
}
}
}
This was really bad perfomance-wise, but it did work. Maybe I could have improved it if I compiled the linq query, but I never got that far. I understand from your comment above that you might have settled on your own workaround to the problem so I am only adding this answer in case it may help future lost souls such as myself.
In the end a TreeView was a better tool for me so I didn't need to do this anyway. Although that began a new adventure, as you can't easily bind a TreeView to a LinqDataSource, but that is a tale for another day.
精彩评论