My SharePoint list has a column that allows multiple lookup values. My C# control (within a webpart) allows the user to make multiple selections from a list box. I split these values into an array - each array member being a selected value that needs to be updated in the same SPListItem column.
I know that the selections are being passed in properly from the list box - I just need to add this group of values to the same column in the SPListItem.
Where am I going wrong?
SPFieldLookupValueCollection MyCollection = new SPFieldLookupValueCollection();
for (int i = 0; i < MyArrayOfSelections.Length; i++)
{
if (MyLookupList["LookupColumn"].ToString() == MyArrayOfSelections[i].ToString())
{
MyID = int.Parse(MyLookupList[i]["ID"].ToString());
SPFieldLookupValue thisSelection = new SPFieldLookupValue(MyID,MyArrayOfSelections[i].ToString());
MySubCollection.Add(thisSelection);
}
}
ListIWantToUpdate["ColumnWithMultipleLookupSelections"] = SubCollection;
ListIWantToUpdate.Update();
site.Update();
}
The last rows of the code example are confusing (maybe it's just variable naming). If you are just updating the data, you never need to update neither the SPList object (this requires "Manage lists" permission on the particular list, nor SPSite ojbect (requires you to be site administrator or owner). So, this code will not run succcessfuly for a regular user.
Related
I have 2 listBoxes with BindingLists as their data sources. The idea is to make a List builder (as MSDN names it), where first listBox shows currently added columns and second listBox shows the rest of available columns. First list contains ViewColumn objects, while the other list contains strings.
I load chosen columns into first listBox from database and then I want to load the rest of available columns into the second listBox (the list itself comes from another place in database). Considering there are no limits on the number of columns, I want to do that in the fastest way possible - what would that be?
Here's some code to visualize that:
ViewTable _view;
BindingList<ViewColumn> _viewColumns = new BindingList<ViewColumn>();
BindingList<string> _detailsColumns = new BindingList<string>();
void CustomInitialize()
{
_view = //get view and its columns
_viewColumns = new BindingList<ViewColumn>(_view.Columns);
listBox_CurrentColumns.DataSource = _viewColumns;
listBox_CurrentColumns.DisplayMember = "Name";
var detailsTable = //get the list of available columns
foreach (var row in detailsTable)
{
//TODO: if _viewColumns does not contain this value, add it to _detailsColumns
_detailsColumns.Add(row.ColumnName);
}
listBox_AvailableColumns.DataSource = _detailsColumns;
}
I think you want to do something like:
_detailsColumns = _allColumns.Except(_viewColumns.Select(c => c.Name))
This should get you all entries in the _allColumns collection excluding the entries in the _viewColumns collection.
I assume here that _allColumns contains the overall collection of possible columns.
for (int i = 0; i < lboxavilableInsName.Items.Count; i++)
{
if (lboxavilableInsName.Items[i].Selected)
{
if (!arraylist1.Contains(lboxavilableInsName.Items[i]))
{
arraylist1.Add(lboxavilableInsName.Items[i]);
arrUpdatedInsValues.Add(lboxavilableInsName.Items[i].Value);
arrUpdatedInsNames.Add(lboxavilableInsName.Items[i].Text);
}
ViewState["UpdatedInsValues"] = arrUpdatedInsValues;
arrUpdatedInsValuestotal = (ArrayList)ViewState["UpdatedInsValues"];
ViewState["UpdatedInsValues2"] = `enter code here`arrUpdatedInsValuestotal;
ViewState["UpdatedInsNames"] = arrUpdatedInsNames;
}
}
Actually I have given selsectionmode="Multiple" in the listbox. That will select me multiple items when I select first time or subsequent time after page gets loaded, but I want that in a code behind saying ex: if I select 2 items 1st time that 2 items will added in the second listbox and I will get the values of those selected items.
If again I select any items after adding previous selection items in 2nd listbox, I want the item value selected at 2nd time along with first two item values. So totally 3 values I want. and I need to send that values to the stored procedure to insert.
Its because you are assigning new values each time to the 2nd listbox, you don't need to assign them, you need to add values within your 2nd listbox, in this way your 2nd listbox will retain all the previous and the new values as well.
Hope it helps.
I am using a Listbox on my windows application. The listbox has a multi-selection option, which users select all the roles the new user will have.
My Listbox is bound to a dataset. The table is Roles, with an ID column and Description column.
When I bound the listbox, I chose the data source being the dataset, the display member to be the description, the value member being the ID and the selected value being the dataset - roles.frolesid
Now when i loop through the listbox's selecteditems, i get only the first item's values etc...
I am trying to assign an int to the current selectedvalue, to get the ID to give to the user.
int num = 0;
foreach (var item2 in lstRoles.SelectedItems)
{
num = Convert.ToInt32(lstRoles.SelectedValue);
}
So if I select 3 roles, for instance Administrator, Capturer and Assessor, I only see the Administrator value.
How do I loop and access the next item? I'm not even using
item2
in my code. Could this be utilised?
For instance:
First iteration:
And it just stays on that selected item, never moving to the next item.
To get list of selected values when the data source is a DataTable, you can use this code:
var selectedValues = listBox1.SelectedItems.Cast<DataRowView>()
.Select(dr => (int)(dr[listBox1.ValueMember]))
.ToList();
But in general Item of a ListBox control may be DataRowView, Complex Objects, Anonymous types, primary types and other types. Underlying value of an item should be calculated base on ValueMember.
If you are looking for a good solution which works with different settings and different data sources, you may find this post helpful. It contains an extension method which returns value of an item. It works like GetItemText method of ListBox.
solved it
int num = 0;
int count = fRoleIDs.Count;
while (num != count)
{
var item = lstRoles.Items[num] as System.Data.DataRowView;
int id = Convert.ToInt32(item.Row.ItemArray[0]);
num += 1;
}
This goes into the listbox's items and according to the index, gets the item as a Row. This then gets me the itemarray, which is ID and Description {0,1}
i have two nested drop down list.
one drop down show group,the other show sub group.
i have coded data source of subgroup drop down list on group drop down list selected indexed change event.
What I'm trying to do is set a drop down list to be whatever its value is in the database when editing an entry.
i have used data row.
i have two tables.documentgroup(GroupId,parentId,groupTitle,subGroupTitle) and documents(DocID,GroupID,Title,url)
in my drop down lists i have added list item like this
<asp:ListItem Text = "--select group--" Value = ""></asp:ListItem>
when i click on editing a document,i have this.
protected void grdDocuments_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "DoEdit")
{
GC.Collect();
GC.WaitForPendingFinalizers();
int DocID = Convert.ToInt32(e.CommandArgument);
ViewState["DocumentID"] = DocID;
ViewState["EditMode"] = "Edit";
DataTable dtDocuments = DataLayer.Documents.SelectRow(DocID).Tables["Documents"];
if (dtDocuments.Rows.Count != 0)
{
DataRow drDocuments = dtDocuments.Rows[0];
txtDocTitle.Text = drDocuments["DocTitle"].ToString();
txtDocPubYear.Text = drDocuments["DocPubYear"].ToString();
ddlDocGroupTitle.SelectedValue = drDocuments["ParentID"].ToString();
ddlDocSubGroupTitle.SelectedValue = drDocuments["DocGroupID"].ToString();
ViewState["DocCurrentUrl"] = drDocuments["DocUrl"].ToString();
mvDocuments.SetActiveView(vwEdit);
}
}
but i get this error
'ddlDocSubGroupTitle' has a SelectedValue which is invalid because it
does not exist in the list of items. Parameter name: value
and this is the same for ddldocgroupTitle.
i have made an inner join between two tables.
what should i do?
I could not really grasp your question, but it looks like you want to have 2 dropdown, and upon selection in the first, the second gets populated/filtered correct?!?
I recommend that you use javascript/Jquery to do so. Upon page load, issue a ajax get request to fill the "main" dropdown, and upon selection on the first one, you issue a second ajax request to fetch the possible values of the second one...
A alternative is to fetch the items for the first dropdown AND all the values possible for the second, storing the result in some hidden-field data. Then upon selection of the first value, you can only filter + display relevant data.
I'm having trouble accessing the value of a calculated field from a list which is in a lookup field on another list in codebehind for SharePoint.
A ListFieldIterator on a page displays a load of options to a user. I need to perform some back-end validation on some particular selections the user has made.
I have a list called "Event Type" from which a user can select Play, performance, display etc. This list has 4 columns - description, enabled, default and filtered. Filtered is a calculated column which is generated based upon the options chosen on the other columns.
The list Events has a column which is a lookup to this list, and which displays the filtered column.
Now on the page this all works great. The options are displayed to the user and they can make their selection. Before adding the calculated field I could access the choice made by doing the below
SPFieldLookup eventTypeField = ListFieldIterator.Item.Fields.GetField("Event_x0020_Type") as SPFieldLookup;
if (eventTypeField.GetFieldValueAsText(ListFieldIterator.Item["Event_x0020_Type"]) == "Performance")
{
// some other logic
errorMessages.Add("There is an error here");
}
Now however when accessing the field in this way I just get an empty string back.
If I attempt to access the chosen item with
string value = eventFields.Item["Event_x0020_Type_x0020_1"].ToString();
Then I get back "8" which is the position in the list of the item I chose. (it changes based on what item in the list I select)
This post Get value of calculate field seems related but I can't see an obvious way to get a calculated field from the lookupfield.
Any suggestions appreciated
It turns out that when using either a lookup column or a lookup column with a calculated field in, as I was, I was going about things the wrong way. This post put me onto the solution. The code is also below.
Essentially I need to access the value stored in the control of the ListFieldIterator and not the value from the item. The code below (from the link above) provides a nice way to do this.
public static List<T> GetControlsOfType<T>(this ControlCollection controls)
{
List<T> resultList = new List<T>();
foreach (Control control in controls)
{
if (control is T)
resultList.Add((T)((object)control));
if (control.Controls.Count > 0)
{
resultList.AddRange(GetControlsOfType<T>(control.Controls));
}
}
return resultList;
}
public object GetFieldValue(ListFieldIterator lfi, string fieldName)
{
FormField formField = lfi.Controls.GetControlsOfType<FormField>().Where(f => f.FieldName == fieldName).FirstOrDefault();
if (formField == null) return null;
return formField.Value;
}