Binding LookupEdit Repository - data-binding

I've three lookupedit repositories (for three columns) in a devexpress xtragrid control. I want to bind lookupedit2 based on a value selected from lookupedit1 and lookupedit3 based on lookupedit2. I can only see the populated elements when I click on the lookupedit. However, it doesn't display the selected element on the grid.
Here is the code i used:
void repositoryLookupEdit1_EditValueChanged(object sender, EventArgs e) {
LookUpEdit edit = gridView.ActiveEditor as LookUpEdit;
int val = Convert.ToInt32(edit.EditValue);
if (!val.Equals(0)) {
var elements = from e in dc.Elements select e;
repositoryLookupEdit1.DisplayMember = "paymentType";
repositoryLookupEdit1.ValueMember = "paymentTypeID";
repZone.DataSource = bindData(elements);
}
}
public BindingSource bindData(object obj) {
BindingSource ctBinding = new BindingSource();
ctBinding.DataSource = obj;
return ctBinding;
}
What could be the possible problem?

I believe this example will be helpful:
How to filter a second LookUp column based on a first LookUp column's value

Related

Get Boolean Value of Each CheckList Items from Content Item in Sitecore

I have an item in Sitecore that contains a content section which is a Checklist. This checklist contains the names of multiple Active Directory groups that I have entered into Sitecore.
When the item loads, I am trying to loop through all of the check boxes that are in the Checklist to see if it is selected.
With help on a previous post, I was able to obtain the names that are listed next to each checkbox by using the following code (You can also see the commented out code that I tried using in order to obtain the value of he checkbox.):
Dim ADCheckList As Sitecore.Data.Fields.MultilistField = Sitecore.Context.Item.Fields("ADGroupAccess")
If ADCheckList IsNot Nothing Then
Dim i As Integer = 0
For i = 0 To ADCheckList.Count - 1
If IsInGroup(ADCheckList.GetItems(i).Fields("name").Value.ToString) Then
Response.Write("User in group. Now let's see if the group is checked.")
''' Trying to see if checkbox is checked or not.
''' Dim isChecked = DirectCast(ADCheckList.GetItems(i).Fields("name").Section, Boolean)
End If
Next
End IF
How can I obtain boolean value of the checkbox?
The field-type only stores the IDs of the items you have selected (as a pipe delimited list) it doesn't store the whole list of possibilities.
If you look at the Template that the item is created from you will see the datasource of the field. This will be a path to an item ie /sitecore/content/home/myfolderofthings the children of this item will be the options you see in the checklist.
You can, for example, loop through the items in the datasource location, get their item.ID property and see if ADCheckList.Items.Contains(item.ID) (or something similar) to get a boolean value.
Stephen's answer correctly pointed out that the checklist field only stores the pipe delimited list of selected IDs, you can see this by viewing the raw values in the content editor or Sitecore Rocks.
I've included some example code that has methods to get a list of all the items shown in a checklist as well as a method to retrieve only the selected items. I hope this helps.
using System;
using System.Collections.Generic;
using Sitecore.Data.Fields;
using Sitecore.Data.Items;
namespace Cms.Website.layouts
{
public partial class CheckList_SO : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var contextItem = Sitecore.Context.Item;
const string checkListFieldName = "List";
SelectedItems.DataSource = contextItem.SelectedItemsInChecklist(checkListFieldName);
SelectedItems.DataBind();
FullItemList.DataSource = contextItem.AllItemsInChecklist(checkListFieldName);
FullItemList.DataBind();
}
}
}
public static class ItemExtensions
{
private static readonly Item[] EmptyItemArray = new Item[] { };
public static IEnumerable<Item> AllItemsInChecklist(this Item item, string checkListFieldName)
{
var fieldItem = item.Template.GetField(checkListFieldName);
if (fieldItem != null)
{
var listSource = fieldItem.Source;
if (!string.IsNullOrEmpty(listSource))
{
var sourceRoot = Sitecore.Context.Database.GetItem(listSource);
if (sourceRoot != null)
{
return sourceRoot.Children.ToArray();
}
}
}
return EmptyItemArray;
}
public static IEnumerable<Item> SelectedItemsInChecklist(this Item item, string checkListFieldName)
{
MultilistField checklist = item.Fields[checkListFieldName];
return checklist != null ? checklist.GetItems() : EmptyItemArray;
}
}
}

How can I populate a drop down box with all the possible SeriesChartType options?

I wish to populate a drop down box with each possible SeriesChartType so that my users may choose an appropriate chart type.
How can I iterate through the SeriesChartType collection (it's in the namespace System.Web.Ui.DataVisualization.Charting) and return each possible option so I can add it to the drop down box?
Thanks.
This worked for me in VB - I had to instantiate a new instance of the SeriesChartType which allowed me to use the [Enum].GetNames Method.
I was then able to add them to the drop down box as shown:
Dim z As New SeriesChartType
For Each charttype As String In [Enum].GetNames(z.GetType)
Dim itm As New ListItem
itm.Text = charttype
ddl_ChartType.Items.Add(itm)
Next
Thanks to everyone for your answers. mrK has a great C alternative to this VB code.
foreach (ChartType in Enum.GetValues(typeof(System.Web.UI.DataVisualization.Charting))
{
//Add an option the the dropdown menu
// Convert.ToString(ChartType) <- Text of Item
// Convert.ToInt32(ChartType) <- Value of Item
}
If this isn't what you're looking for, let me know.
You could bind data in the DataBind event handler:
public override void DataBind()
{
ddlChartType.DataSource =
Enum.GetValues(typeof(SeriesChartType))
.Cast<SeriesChartType>()
.Select(i => new ListItem(i.ToString(), i.ToString()));
ddlChartType.DataBind();
}
and then retrieve the selected value in the SelectedIndexChanged event handler like this:
protected void ddlChartType_SelectedIndexChanged(object sender, EventArgs e)
{
// holds the selected value
SeriesChartType selectedValue =
(SeriesChartType)Enum.Parse(typeof(SeriesChartType),
((DropDownList)sender).SelectedValue);
}
Here's a generic function:
// ---- EnumToListBox ------------------------------------
//
// Fills List controls (ListBox, DropDownList) with the text
// and value of enums
//
// Usage: EnumToListBox(typeof(MyEnum), ListBox1);
static public void EnumToListBox(Type EnumType, ListControl TheListBox)
{
Array Values = System.Enum.GetValues(EnumType);
foreach (int Value in Values)
{
string Display = Enum.GetName(EnumType, Value);
ListItem Item = new ListItem(Display, Value.ToString());
TheListBox.Items.Add(Item);
}
}

ASP.Net Custom Control

I am developing a custom control that needs to display a dropdownlist as a composite control.
The drop down list gets populated from a Rest web service. The problem I am facing is that the dropdownlist only has DataTextField and DataValueField but I need a way of storing more values in the control i.e. I have a couple of other properties I need to access for the selected item.
What is the best way of going about this?
Here is the code I have so far:
[ValidationProperty("SelectedValue")]
public class SelectSurveyControl : Panel
{
private DropDownList ddlSurveys;
public string SelectedSurveyId
{
get
{
return SelectedValue;
}
}
public string SelectedSurveyJavascriptEmbedCode
{
get
{
return this.ddlSurveys.SelectedItem.Attributes[""];
}
}
public string SelectedValue
{
get
{
return ddlSurveys.SelectedValue;
}
set
{
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
ddlSurveys.SelectedValue = value;
}
}
protected override void OnLoad(EventArgs e)
{
base.OnInit(e);
if (ddlSurveys == null)
{
ddlSurveys = new DropDownList();
}
IList<Survey> surveys = GetSurveys();
this.ddlSurveys.DataSource = surveys;
this.ddlSurveys.DataTextField = "title";
this.ddlSurveys.DataValueField = "id";
this.ddlSurveys.DataBind();
ddlSurveys.SelectedValue = this.SelectedValue;
ddlSurveys.CssClass = "umbEditorTextFieldMultiple charlimit";
ddlSurveys.Attributes.Add("SurveyId", SelectedSurveyId);
ddlSurveys.Attributes.Add("JavascriptEmbedingCode", SelectedSurveyId);
this.Controls.Add(ddlSurveys);
}
public IList<Survey> GetSurveys()
{
...
}
}
Try using a string join/split to store and retrieve the various values, then you don't have to customize your dropdown list very much.
For Example:
Text: Some Title
Value: 1|testing test|2/12/2010
This will let you store as many values as you want, so long as you choose an appropriate character to join and split on. I usually use the bar, as in my example above.
Side Note: I was looking at your selected value set handler and it needs some tweaking. You shouldn't check for a null drop down list, instead you should call EnsureChildControls() before each get and set instead. Make sure you override the CreateChildControls() method and create your controls there.
You could use a hidden field and iterate thru a copy of the returned Surveys like this:
foreach(Survey s in Surveys){
string val = s.id + ":" + s.<property1> + ":" + s.<property2>;
hiddenField.Value += val +",";
}
When you need to read from the hidden field, you use String.Split to separate the values into arrays using ',' as the separator and in each array, you split again using ':'.
In the first split Array1[0] who be the survey id and Array1[n!=0] would be the properties of the Survey with the id = Array1[0]. Array[n!=0] would then be split into Array2.
I would suggest handling empty property values with an empty string or something or else you might end up with unequal lengths especially if you specify StringSplitOptions.RemoveEmptyEntries.
Agricfowl

Have to select gridview row twice for dropdown to select correctly

I'm using the code below to extract data from a gridview and populate it into textboxes for the days and two drop downs for Project and Category.
For some rows in the gridview everything but the category ddl populates correctly. If I click the row a second time the category ddl displays the correct category.
Can anyone tell me why I have to click twice for some rows? And how do I fix this?
Thank you
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
//// Get the currently selected row using the SelectedRow property.
GridViewRow row = GridView1.SelectedRow;
txtSunday.Text = (row.Cells[6].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtMonday.Text = (row.Cells[7].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtTuesday.Text = (row.Cells[8].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtWednesday.Text = (row.Cells[9].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtThursday.Text = (row.Cells[10].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtFriday.Text = (row.Cells[11].Controls[0] as DataBoundLiteralControl).Text.Trim();
txtSaturday.Text = (row.Cells[12].Controls[0] as DataBoundLiteralControl).Text.Trim();
// Set ProjectList ddl to Project in selected row
if (ProjectList.Items.FindByText(row.Cells[2].Text.Trim()) != null)
{
ProjectList.ClearSelection();
ProjectList.Items.FindByText(row.Cells[2].Text.Trim()).Selected = true;
}
/// This is the ddl that doesn't always populate correctly unless you click the
/// gridview row selector twice
// Set CategoryList ddl to Category in selected row
if (CategoryList.Items.FindByText(row.Cells[4].Text.Trim()) != null)
{
CategoryList.ClearSelection();
CategoryList.Items.FindByText(row.Cells[4].Text.Trim()).Selected = true;
}
}
I'm not sure why it's taking two clicks to get your drop down list to select correctly, but it might have to do with postback event ordering/ViewState issues. One thing you may want to consider is using the data you're binding the grid to rather than the text of the controls in the grid. IOW, assuming you're binding to an collection of objects like this:
public class ProjectSchedule
{
public string Project {get;set;}
public int CategoryId {get;set;}
public string Category {get;set;}
public string Sunday {get;set;}
public string Monday {get;set;}
public string Tuesday {get;set;}
public string Wednesday {get;set;}
public string Thursday {get;set;}
public string Friday {get;set;}
public string Saturday {get;set;}
}
Then, in the SelectedIndexChanged event handler, get your data like this:
GridViewRow row = GridView1.SelectedRow;
ProjectSchedule ps = row.DataItem as ProjectSchedule;
if (ps != null)
{
txtSunday.Text = ps.Sunday;
// the rest of the days...
ListItem categoryItem = CategoryList.Items.FindByText(ps.Category);
if (categoryItem != null)
{
CategoryList.ClearSelection();
categoryItem.Selected = true;
}
// same with ProjectList
}
Assuming your controls are going to land in the same column every time limits maintainability. For instance, say the requirements change to say the columns with the days are before the Project column. That's a lot of indices to change.
It would be even better if you have your categories and whatnot indexed by something (e.g., the CategoryId property I smuggled into the ProjectSchedule object above), then you could look up the item by value instead of by text, relieving another point of failure.
I think I figured this out. I needed to rebind the category ddl after setting the project
// Set ProjectList ddl to Project in selected row
if (ProjectList.Items.FindByText(row.Cells[2].Text.Trim()) != null)
{
ProjectList.ClearSelection();
ProjectList.Items.FindByText(row.Cells[2].Text.Trim()).Selected = true;
}
// Set CategoryList ddl to Category in selected row
// I added this line and it seems to work now
CategoryList.DataBind();
if (CategoryList.Items.FindByText(row.Cells[4].Text.Trim()) != null)
{
CategoryList.ClearSelection();
CategoryList.Items.FindByText(row.Cells[4].Text.Trim()).Selected = true;
}

Binding sclar values in C# grid controls

Recently I have been using both the ASP.Net GridView Control and the WinForms DataGridView to display data dynamically. In both cases I have been using various generic Lists as the datasource (List<T>). When this list in as a collection of types with properties defined, these controls have no problem binding to a named property, and in the case of the DataGridView will display the properties as headers with the values for each property as the rows.
However when I have a collection of strings or ints for example, these controls have trouble binding to the values contained in the lists. I'm creating my ASP GridView control dynamically so its not defined in the page untill it is needed so I don't think a binding expression will work here, although I'm new to binding expressions so I could be wrong:
GridView grid = new GridView();
grid.AutoGenerateColumns = false;
grid.CssClass = "summaryTable";
grid.Columns.Add(new TemplateField { HeaderText = "Error No.", ItemTemplate = new DataGridAutoNumber(grid) });
grid.Columns.Add(new BoundField { HeaderText = "Error Description", DataField="Value" });
grid.DataSource = validator.ValidationErrors;
grid.DataBind();
In the above example validator.ValidationErrors is a list of strings. In order to get the GridView to bind the string values I had to wrap them in a type I created:
public class ValueItem<T>
{
T value;
public ValueItem(T valueIn) { value = valueIn; }
public T Value { get { return value; } }
}
This type works for both GridView and DataGridView and allows me to create a List<ValueItem<T>>() of any value type so I can bind it to a Grid type control.
Now am I missing something here or do these controls just not work well with collections of value types?
Apologies for the long question!
P.S. As a side note if anyone knows how to create an autonumber column in a GridView in the code not the script, please let me know. My solution was this:
public class DataGridAutoNumber : ITemplate
{
GridView grid;
public DataGridAutoNumber(GridView gridIn) { grid = gridIn; }
#region ITemplate Members
public void InstantiateIn(Control container)
{
container.Controls.Add(new Label{ Text=(grid.Rows.Count+1).ToString()});
}
#endregion
}
you already know how to add Label to GridView.
Here is one logic to add auto numbering i.e. row number to grid
Untested code
protected void gv_DataBound(object sender, EventArgs e)
{
int pageIndex = gv.PageIndex;
int pagesize = 20;
int count = pagesize * pageIndex;
foreach (GridViewRow row in gv.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
count ++;
Label lbl = row.FindControl("lblAutoNumber") as Label;
lbl.Text = count.ToString();
}
}
}

Resources