Set default value of telerik:GridDropDownColumn inside of telerik:RadGrid - asp.net

I have a telerik:RadGrid that is bound to a SQL Data Source. One of the columns is for "Location" which is really a look up value in another table.
<telerik:GridDropDownColumn
DataField="d_location_id"
DataSourceID="dsLocation"
UniqueName="d_location_id"
DataType="System.Int32"
ListValueField="d_location_id"
ListTextField="Abbreviation"
HeaderText="Location">
</telerik:GridDropDownColumn>
My list of locations is stored in an ObjectDataSource, which is bound to a static DataTable and sorted alphabetically for me already. What I would like to do is be able to set the default option for this dropdown.
For example, suppose I have the following locations:
1 Home
2 Work
3 Parents
4 Car
I would like to have Parents be my default value.
This sample on Telerik shows something similar to what I'm trying to do. If you click "Add New Record", you'll notice the default city is Kirkland and I'm trying to figure out how to use London as the default when adding a new record.

Not sure if it is the best or most straightforward way or not, but it does work.
protected void gridMyInfo_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
if (e.Item.IsInEditMode && e.Item.ItemIndex < 0)
{
GridEditableItem editedItem = e.Item as GridEditableItem;
GridEditManager editMan = editedItem.EditManager;
GridDropDownListColumnEditor editor = editMan.GetColumnEditor("d_location_id") as GridDropDownListColumnEditor;
editor.ComboBoxControl.SelectedIndex = editor.ComboBoxControl.Items.FindItemIndexByText("Parents");
}
}

Related

Unique ID's for buttons in gridview?

A 508 Scan flagged the fact that we have identical id's for buttons in gridviews, and I'm wondering how to get around this. For some of these buttons we can remove the id's entirely and they don't seem to affect functionality, but others actually do have back-end code that enables/disables them based on other factors. Here's the front-end code:
<asp:TemplateField HeaderText="Accept" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:Button
ID="btnAccept"
runat="server"
Text="Accept Data"
CssClass="inherited"
CommandName="AcceptData"
CommandArgument="<%# ((GridViewRow) Container).RowIndex %>" />
</ItemTemplate>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:TemplateField>
And here is some of the backend code that pertains to this button:
protected void gvDashboard_RowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int rowIndex = e.Row.RowIndex;
Button btnAccept = e.Row.FindControl(#"btnAccept") as Button;
Button btnRemove = e.Row.FindControl(#"btnRemove") as Button;
bool errors = (bool)gvDashboard.DataKeys[e.Row.RowIndex][#"Errors"];
string fileType = (string)gvDashboard.DataKeys[e.Row.RowIndex][#"FileType"];
string processingStatus = (string)gvDashboard.DataKeys[e.Row.RowIndex][#"ProcessingStatus"];
bool accepted = (bool)gvDashboard.DataKeys[e.Row.RowIndex][#"Accepted"];
int records = 0;
if (gvDashboard.DataKeys[e.Row.RowIndex][#"Records"] is System.DBNull)
{
int recordsColumnIndex = Utilities.GetColumnIndexByHeaderText(gvDashboard, #"Records");
e.Row.Cells[recordsColumnIndex].Text = #"0";
}
else
{
records = (int)gvDashboard.DataKeys[e.Row.RowIndex][#"Records"];
}
if (fileType == #"CN" || fileType == #"CP")
{
if ((DBNull.Value.Equals(gvDashboard.DataKeys[e.Row.RowIndex][#"ZipId"]))
|| ((int)gvDashboard.DataKeys[e.Row.RowIndex][#"ZipId"] == 0))
{
// CN or CP did not come from a zip file
if ((accepted))
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
else
{
btnAccept.Enabled = false;
btnRemove.Enabled = false;
}
}
if (accepted || processingStatus == #"I" || processingStatus == #"N")
{
btnAccept.Enabled = false;
}
}
}
catch (Exception ex)
{
DAL.ErrorLog(#"FilteredDashboard.gvDashboard_RowDataBound: Row: " + e.Row.RowIndex.ToString() + " " + ex.Message);
}
}
Ideally I would like to be able to add on an autogenerated number onto the front-end ID, but then account for ID's with the same initial string (like 'btnAccept' or 'btnRemove') regarless of their additional numeric suffixes. Is that possible at all?
ASP.NET Webforms auto generates button IDs for each control, unless you set it to
ClientIDMode="Static"
If you'd like to make sure the IDs are unique, set
ClientIDMode="AutoID" //this is the default setting for all webform controls, and autogenerates an ID
So the issue is probably coming from somewhere else, you can check it yourselves in the inspector of your browser.
as noted in answer by Zee - you can use find control with the one name for each row - however, each row control - including buttons DOES get its own id.
This problem should not exist - and as a general rule never has been a issue. Each row of the GV will auto generate new id for each row of controls. However, while new "id" are generated, you can on the row data bind events use find control with the control name without issue.
Also, you really don't need to save/put in the row index for hte button command args. In fact, you can also get the database primary key - and NOT even display or have the PK displayed in each row.
Assuming you have datakeys set (say to PK "id" column), then you can then use a simple button row click event for a button on the gv row.
You can't double click on the button to add the event (since it inside the GV), but you can use intel-sense like this:
Just type in onclick= , and when you hit "=", the you get intel sense like this:
So, you can choose create new event.
Now, in this plane jane button event you can
Get any value or control of that row.
Get the row index - no need to put in markup
Get the row primary key database row ID - again no need to have in markup.
So, the code behind the button can look like this:
protected void Button1_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
GridViewRow gRow = btn.NamingContainer as GridViewRow;
Debug.Print("Row index click = " + gRow.RowIndex);
Debug.Print("Data base PK ID = " + GridView1.DataKeys[gRow.RowIndex]["ID"]);
// And you are free to using gRow.FindControl, or even the cells collection
// for non templated values.
// eg: gRow.Cells[0].Text
Output:
Row index click = 3
Data base PK ID = 11
Note how I used datakeys setting. This is REALLY nice for security, since I don't have to expose client side the database row PK id used. And note how I also picked up the current GV row index - again all without having to put or mess with that stuff in the actual gv row. So, you don't even need to use command Argument either. And you don't need to use commandName either. You ONLY need to set CommandName if you want the Gv selected index event to fire. (so, you might need it), but as a general rule, just drop in a plane jane button - wire up the event, and get the current row with "naming container" as I did. And then you get the GV row, and with that you have everything you need - including rowindex, and even use of datakeys as I pointed out.
In fact, this means for the most part I don't bother with the built in GV events - they are not worth your time in most cases.

Telerik RadGrid GridDataItem - how to determine if column exists?

I'm using a base class to modify the behavior of any Telerik RadGrid that appears on my ASP.Net pages. In the base class, I want to perform certain operations (set Css, tool tips, etc) on many common columns, but not every common column exists in every grid.
In the ItemDataBound event I'm getting an instance to the GridDataItem and in turn I want to get a reference to one or more of the contained cells of the GridDataItem:
var cell = gridDataItem["ColumnUniqueName"]
Problem is that this throws a GridException if the named column doesn't exist:
Cannot find a cell bound to column name 'ColumnUniqueName'
Is there a way to test for existence of a column by name before referencing it or am I
stuck using try catch?
Will sent me on the right path:
var tableView = gridDataItem.OwnerTableView;
var gridColumn = tableView.Columns.FindByUniqueNameSafe(uniqueName);
if (gridColumn != null)
{
var cell = gridDataItem[gridColumn];
...
Try using the RenderColumns collection:
protected void rgGrid_ItemDataBound(object sender, GridItemEventArgs e)
{
if (e.Item is GridDataItem)
{
bool found = (from d in rgGrid.MasterTableView.RenderColumns select d).Any(d => d.UniqueName == "ColumnUniqueName");
}
}

DevExpress XtraGrid - Change/disable a cell in column2 when column1 changes

I have 2 columns I'm working with in an XtraGrid. When Column1's value changes, I'd like to perform some logic and possibly change the value of Column2 and disable Column2 as well. You can see my code below, but I have 3 problems:
My CustomRowCellEdit function seems to run non-stop in the background.
The SetRowValue on Column2 doesn't seem to really happen unless I click away from the row; I need the change to happen as soon as Column1 is changed.
How can I disable within my IF block?
I've added the following Event to a Grid:
this._myGridView.CustomRowCellEdit +=
new DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventHandler(
this.myGridView_CustomRowCellEdit);
Here is the Event:
private void myGridView_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e)
{
if (e.Column.FieldName == "Column1" && e.RowHandle >= 0)
{
GridView gv = sender as GridView;
string value1 = gv.GetRowCellValue(e.RowHandle, gv.Columns["Column1"]).ToString();
if (value1 == "something")
{
gv.SetRowCellValue(e.RowHandle, gv.Columns["Column2"], someOtherValue);
// I'd like to disable Column2 in this IF logic.
}
}
}
In the DevX docs, there is a note about the CustomRowCellEdit event that says
Due to the XtraGrid control's infrastructure, the CustomRowCellEdit event fires frequently - each time a cell is refreshed. Therefore, do not implement complex logic for your CustomRowCellEdit event handler...
Given your stated requirements, my approach would be to use the CellValueChanged event instead of CustomRowCellEdit. Your handler could then say something like
private void myGridView_CellValueChanged(object sender, CellValueChangedEventArgs e) {
if (e.Column.FieldName != "Column1") return;
GridView gv = sender as GridView;
if (e.Value == "something") {
gv.SetRowCellValue(e.RowHandle, gv.Columns["Column2"], someOtherValue);
}
}
To make an individual cell non-editable at runtime, see this topic on the DevExpress support site.
how to set readyonly for rows at runtime using Devxpress Grid Contorl.
Essentially what you need to do is handle the grid view's ShowingEditor event, and using the FocusedRowHandle and FocusedColumn properties, decide whether or not to allow editing for the current cell. To disable editing, set the Cancel property of the CancelEventArgs to true.
Hope this helps.

DevExpress edit template combobox value to parameter

I have two pre populated combo boxes with value = “ID” and Text = Relevant data...
I am doing an edit in a grid view and I adjusted the template to have the two combo boxes (each relevant field has its own).
I have searched high and low and I assume this is so easy people don’t even ask about it... but if you see below the combo boxes do not populate the parameters with the value of the combo boxes.
So I have tried this:
protected void aspxGridviewUsers_RowUpdating(object sender, DevExpress.Web.Data.ASPxDataUpdatingEventArgs e)
{
e.NewValues["StoreID"] = GetStoreID();
e.NewValues["GroupID"] = GetGroupID();
}
protected int GetStoreID()
{
ASPxComboBox CBID = new ASPxComboBox();
CBID = aspxGridviewUsers.FindEditFormTemplateControl("ASPxComboBoxStoreEdit") as ASPxComboBox;
return Convert.ToInt32(CBID.SelectedItem.Value.ToString());
}
protected int GetGroupID()
{
ASPxComboBox CBID = new ASPxComboBox();
CBID = aspxGridviewUsers.FindEditFormTemplateControl("ASPxComboBoxGroupEdit") as ASPxComboBox;
return Convert.ToInt32(CBID.SelectedItem.Value.ToString());
}
This did not work. What am I doing wrong here?
How can I use those values in the comboboxes to update against my update statement?
I would suggest that you use the following code:
return Convert.ToInt32(CBID.Value);
code. Does it work for you?

How can I retrieve a subset of data from entity object data source and pass to another page

I am playing about just now trying to teach myself a little bit about the entity framework.
I have a Gridview data bound to a Entity Date Source using the Entity Framework. If I select certain items in that list I then wish to redirect another page and populate another gridview with just the items selected (but with more detail, different includes/navigation properties)
This is probably the most simple thing but I have spent 2 hours banging my head on the wall trying to get this to work.
Essentially I have a continue button which when clicked should identify all the UIDs (a column in the gridview) of the rows and allow me to subset to just these rows and pass them to another page to be rebound to another datagrid
Any ideas???
Well, the big picture is that you should get those IDs, pass them to the other page, and then use a query with Contains; see this question for an idea of how to use it:
How search LINQ with many parametrs in one column?
Assuming you haven't used DataKeys in your GridView, this would be my approach.
Page 1
protected void Button1_Click(object sender, EventArgs e)
{
var checkedItems = new List<int>();
foreach (GridViewRow row in GridView1.Rows)
{
var checkbox = (CheckBox)row.FindControl("CheckBox1");
if (checkbox.Checked)
{
checkedItems.Add(int.Parse(row.Cells[1].Text));
}
}
Session["checkedItems"] = checkedItems;
Response.Redirect("Page2.aspx");
}
Page 2
protected void Page_Load(object sender, EventArgs e)
{
var checkedItems = (List<int>)Session["checkedItems"];
Session["checkedItems"] = null;
foreach (var checkedItem in checkedItems)
{
Response.Write(checkedItem);
}
}
Using the IDs in the checkedItems List you can now query those from you DB and finally assign the Result to your GridView on the second page.
Instead of using Session you could pass the IDs via QueryString.

Resources