Exporting a filtered Grid data In Telerik RadGrid - telerik

When exporting a rad grid data if the user has it filtered in any way the grid should just export the filtered data not the entire dataset - Any idea how to achieve this?
Regards - Hemant

Here is a solution that allows one to get a filtered, sorted list of data items using the current filter and sort settings from a Telerik RadGridView control (Silverlight version).
using Telerik.Windows.Data;
.
.
.
IEnumerable<MyClass> itemsToDisplay { get; set; } //The RadGridView is bound to this property
public void DoSomethingWithFilteredAndSortedDisplayItems(RadGridView rgv)
{
IQueryable<MyClass> iqItems = itemsToDisplay.AsQueryable();
FilterDescriptorCollection filter = rgv.FilterDescriptors;
SortDescriptorCollection sort = rgv.SortDescriptors;
List<MyClass> fsItems = iqItems.Where(filter).Sort(sort).ToIList() as List<MyClass>;
if (fsItems != null && fsItems.Count > 0)
{
DoSomethingWithDisplayItems(fsItems);
}
}
public void DoSomethingWithDisplayItems(IEnumerable<MyClass> list)
{
... //Do something
}

I think that if you assign the filtered set of data to the grid before calling the export method (which internally rebinds it), you will get the filtered values in the exported file.

Related

How to create separate DetailTable on each row in a RadGrid?

I have a telerik radgrid where columns and detail tables are declared like:
<telerik:RadGrid>
<Columns>
<telerik:GridBoundColumn/>
<telerik:GridBoundColumn/>
</Columns>
<DetailTables>
<telerik:GridTableView
<Columns>
<telerik:GridBoundColumn/>
<telerik:GridBoundColumn/>
</Columns>
</telerik:GridTableView
</DetailTables>
</telerik:RadGrid>
Which gives a nested grid like this:
Now, what I want is to be able to specify a detail table (those sub tables) per row, programmatically.
(I cannot be sure that the columns for the nested table that comes up when I expand the line fgvbvb will be the same as the columns when expanding the line xcxcv).
I have tried, without luck in the OnDataBound handler of the radgrid (in which I omitted <DetailTables>) to access the data structure for nested tables like this:
protected void OnRadGridDataBound(object sender, EventArgs e)
{
foreach (GridDataItem item in grdActivitiesToCopy.MasterTableView.Items)
{
var dg = item.ChildItem.NestedTableViews[0];
}
}
This will overindex the array NestedTableViews because it is empty. Also, item.ChildItem.NestedTableViews has no setter.
How do I populate each row with a detail table one by one manually?
According to Telerik:
RadGrid does not support mixing declarative grid columns with grid
columns added dynamically at runtime. You should either create all the
columns in the grid programmatically, or else define them all in the
ASPX file. When creating Detail tables, it should be created in the
PageInit event.
Creating a Hierarchical Grid Programmatically:
You should follow these basic steps in order to create hierarchical
RadGrid programmatically in the code-behind (having a data source
control for data content generation):
Create the grid dynamically in the Page_Init handler of the page by
calling its constructor.
Specify the preferred settings for your grid instance through its
properties.
Create columns for the grid dynamically. Keep in mind that you have to
first set their properties and then add them to the
MasterTableView/GridTableView collection (discussed in the first
paragraph of this same topic). Thus, their ViewState will be properly
persisted (as LoadViewState is raised after the Init event of the
page).
Set the proper ParentTableRelations for the GridTableViews (along with
their MasterKeyField and DetailKeyField attributes) and DataKeyNames
for the MasterTableView/GridTableViews in the code-behind of the page.
Assign data sources (through the DataSourceID attribute) for each
table in the grid hierarchy.If you do not want to use declarative
relations, generate the data in the NeedDataSource/DetailTableDataBind
handlers of the grid. On DetailTableDataBind you can determine which
data source should be related to the currently bound GridTableView by
checking its Name/DataSourceID property. Here, the Name property must
have a unique value for each detail table (this value has to be
defined previously by the developer) and the DataSourceID is the ID of
the DataSource control responsible for the corresponding detail table
content generation.
Code Sample:
RadGrid RadGrid1 = new RadGrid();
RadGrid1.DataSourceID = "SqlDataSource1";
RadGrid1.MasterTableView.DataKeyNames = new string[] { "CustomerID" };
RadGrid1.Skin = "Default";
RadGrid1.Width = Unit.Percentage(100);
RadGrid1.PageSize = 15;
RadGrid1.AllowPaging = true;
RadGrid1.AutoGenerateColumns = false;
//Add columns
GridBoundColumn boundColumn;
boundColumn = new GridBoundColumn();
boundColumn.DataField = "CustomerID";
boundColumn.HeaderText = "CustomerID";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
boundColumn = new GridBoundColumn();
boundColumn.DataField = "ContactName";
boundColumn.HeaderText = "Contact Name";
RadGrid1.MasterTableView.Columns.Add(boundColumn);
//Detail table - Orders (II in hierarchy level)
GridTableView tableViewOrders = new GridTableView(RadGrid1);
tableViewOrders.DataSourceID = "SqlDataSource2";
tableViewOrders.DataKeyNames = new string[] { "OrderID" };
GridRelationFields relationFields = new GridRelationFields();
relationFields.MasterKeyField = "CustomerID";
relationFields.DetailKeyField = "CustomerID";
tableViewOrders.ParentTableRelation.Add(relationFields);
RadGrid1.MasterTableView.DetailTables.Add(tableViewOrders);
Please refer to this help article for more details:
http://docs.telerik.com/devtools/aspnet-ajax/controls/grid/defining-structure/creating-a-radgrid-programmatically#creating-a-hierarchical-grid-programmatically
First of all , because of the life cicle of a asp page. You can't access to a event on a detail table.
If you need to access detail tables , items etc ..
You need to add an method to the PreRender in the MasterTableView like this:
<MasterTableView DataSourceID="myDataSource"
AllowMultiColumnSorting="True"
DataKeyNames="Key1,Key2,KeyN"
HierarchyDefaultExpanded="True"
OnPreRender="Unnamed_PreRender" >
The method will recursively iterate through the grid.
The way you do it can change depending on your HieararchyLoadMode.
So this is my way to do it, easiest way exist if you are on Client or Serverbind mode.
Traversing and load mode by the telerik doc .
I'm pretty sure you don't want to :
"populate each row with a detail table one by one manually"
You want to have Multiple table at a Sub Level in your grid and display the rigth one programmatically.
And this is can be done in two easy step:
1/. Create every Detail table in your apsx page.
Please refer to this documentation for more information :
Several tables at a level
2/. Handle the display:
protected void Unnamed_PreRender(object sender, EventArgs e)
{
if (!IsPostBack) myControler(MASTERGRID.MasterTableView);
}
private void myControler(GridTableView gridTableView)
{
GridItem[] nestedViewItems = gridTableView.GetItems(GridItemType.NestedView);
foreach (GridNestedViewItem nestedViewItem in nestedViewItems)
{
foreach (GridTableView nestedView in nestedViewItem.NestedTableViews)
{
if (nestedView.Name == "mytable12" && nestedView.Items.Count == 0)
{ HideExpandColumn(nestedView, nestedView.ParentItem["ExpandColumn"]); }
else if (nestedView.Name == "mytable23")
{
if (nestedView.Items.Count == 0)//
HideExpandColumn(nestedView, nestedView.ParentItem["ExpandColumn"]);
else
{ }
}
if (nestedView.HasDetailTables)
{ myControler(nestedView); }
}
}
}
private void HideExpandColumn(GridTableView _GNVI, TableCell _cell)
{
if (_cell.Controls.Count > 0)
{
_cell.Controls[0].Visible = false;
_cell.Text = " ";
}
_GNVI.Visible = false;
}
You can hide a detail table using :
HideExpandColumn(nestedView, nestedView.ParentItem["ExpandColumn"]);
Or you can hide the parent of the detail table you tested using the detail table that is in param of the controler :
HideExpandColumn(gridTableView, nestedView.ParentItem["ExpandColumn"]);
HideExpandColumn will hide the expand control that stay sometimes even if you hide th detail table.
Bonus: If you need to access to a control in a detail table.
You can use this:
public static class ControlExtensions
{
public static Control FindIt(this Control control, string id)
{
if (control == null) return null;
Control ctrl = control.FindControl(id);
if (ctrl == null)
{
foreach (Control child in control.Controls)
{
ctrl = FindIt(child, id);
if (ctrl != null) break;
}
}
return ctrl;
}
}
Calling it in your controler like this :
else if (nestedView.Name == "DetailPV")
{
if (nestedView.Items.Count == 0)
HideExpandColumn(gridTableView, nestedView.ParentItem["ExpandColumn"]);
else
{
RadLabel ctrl = (RadLabel)this.FindIt("RadLabel11");
ctrl.Text += "<b>" + nestedView.Items.Count.ToString() + "</b>";
}

Telerik OpenAccess - Search With Non-Persistent Property

I'm using Telerik OpenAccess and SQL Server on a project and I need to be able to search by what someone's age will be on a certain date. The problem that I am running into is that the person's date of birth is stored in one table and the date to compare to is in another table, which prevents me from using a computed column. They are, however, joined together so that I can calculate the age by creating my own non-persistent property in the partial class like so:
public partial class Student
{
[Telerik.OpenAccess.Transient]
private int? _ageUponArrival;
public virtual int? AgeUponArrival
{
get
{
try
{
var dob = DateTime.Parse(this.StudentProfiles.First().Person.YearOfBirth);
var programStart = (DateTime)(this.StudentPrograms.First().ProgramStart);
this._ageUponArrival = programStart.Year - dob.Year;
if (dob > programStart.AddYears(-(int)(this._ageUponArrival)))
{
(this._ageUponArrival)--;
}
}
catch (Exception e)
{
this._ageUponArrival = null;
}
return _ageUponArrival;
}
set { }
}
}
Please ignore how bad the tables are set up, it's something that I inherited and can't change at this point. The problem with this approach is that the property is not available to search on with Linq. I know that I could create a view that would do this for me, but I would much rather not have to maintain a view just for this. Is there any way at all to create a calculated property through Telerik that would be calculated on the db server in such a way as to be searchable?
It appears that this is not possible at this point. http://www.telerik.com/community/forums/orm/linq-questions/dynamic-query-with-extended-field.aspx

unable to get multiple entries in SelectEntries of DotNetZip

I'm trying to use DotNetZipLib-DevKit-v1.9 in my MVC3 Project to extract the files to a specific folder.
What i want is -- How to add multiple entries in zip.SelectEntries method.
Here is my code in controller action:
public ActionResult ExtractZip(string fileName, HttpPostedFileBase fileData)
{
string zipToUnpack = #"C:\Users\Public\Pictures\Sample Pictures\images.zip";
string unpackDirectory = System.IO.Path.GetTempPath();
using (ZipFile zip1 = ZipFile.Read(zipToUnpack))
{
// here, we extract every entry, but we could extract conditionally
// based on entry name, size, date, checkbox status, etc.
var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;");//This shows `0` items in collections
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}
}
return Json(true);
}
In this line var collections = zip1.SelectEntries("name=*.jpg;*.jpeg;*.png;*.gif;"); if i specify only single extension ,it works fine
ex:
var collections = zip1.SelectEntries("name=*.gif"); this works good
I've also seen SelectEntries method here, but it doesn't help though
How to add multiple entries ?
Finally i could answer my own question.
Inorder to select multiple entries we need to use OR and to select multiple entries use the following code:
var collections = zip1.SelectEntries("(name=*.jpg) OR (name=*.jpeg) OR (name=*.png) OR (name=*.gif)");
foreach (var item in collections)
{
item.Extract(unpackDirectory, ExtractExistingFileAction.OverwriteSilently);
}

Using JQGrid with custom paging in Asp.Net MVC

I am using JQGrid with the Trirand.Web.Mvc class, and trying to figure out how to do custom paging.
I have seen the paging demos here
The problem with these demos is that they bind directly to a linq context object and lets MVC take care of the paging.
// This method is called when the grid requests data. You can choose any method to call
// by setting the JQGrid.DataUrl property
public JsonResult PerformanceLinq_DataRequested()
{
// Get both the grid Model and the data Model
// The data model in our case is an autogenerated linq2sql database based on Northwind.
var gridModel = new OrdersJqGridModel();
var northWindModel = new NorthwindDataContext();
// return the result of the DataBind method, passing the datasource as a parameter
// jqGrid for ASP.NET MVC automatically takes care of paging, sorting, filtering/searching, etc
return gridModel.OrdersGrid.DataBind(northWindModel.OrdersLarges);
}
The data set I want to bind to is quite complex and I am returning it from a stored procedure, which does the paging for me.
So all I have to give JQGrid is the correct size of rows for a specific page of the entire resultset. I can also return the total row count.
So I have my results in a List myListOfObjects.
I can pass this into the DataBind using myListOfObjects.AsQueryable()
The problem is, JQGrid thinks there is only {page size} rows, so does not display any of the paging options.
Is it possible to pass in the total row count?
Other grids, like Teleriks MVC grid allows you to pass in the Total row count, and it displays the paging correctly
Ok, so I've managed to solve this myself. There may be other ways to do it, if so I'd love to hear them!
The JQGrid.DataBind produces an JsonResult object, whose Data value is set to Trirands own object Trirand.Web.Mvc.JsonResponse
It's an internal class to their Trirand.Web.Mvc, so i had to copy its structure which I could see using Visual Studio debugging.
It has:
page - the current page number
records - the total record count
rows - of type Trirand.Web.Mvc.JsonRow (which I need to replicate too)
total - the total number of pages needed
JsonRow looks like:
cell - a string array of your columns
id - your row ID
So my code looked like this:
var jsonList = new List<JSONRow>();
myData.ForEach(x => jsonList.Add(new JSONRow(x)));
var jsonResult = Json (new
{
page = page,
rows = jsonList.ToArray(),
records = totalRows,
total = Math.Round((double)totalRows / rows, MidpointRounding.AwayFromZero)
}, JsonRequestBehavior.AllowGet);
return jsonResult;
My JsonRow looks like this:
public class JSONRow
{
public string[] cell { get; set; }
public string id { get; set; }
public JSONRow(MyObjectType myObject)
{
id = myObject.id;
cell = new string[3];
cell[0] = myObject.Col1;
cell[1] = myObject.Col2?? "";
cell[2] = myObject.Col3?? "";
}
}

Why RadFilter is not detecting Columns correctly?

I am having trouble that RadFilter is not detecting the columns correctly. I bind my RadGrid through code in Asp like:
RadGrid1.DataSource = myDataSource;
RadGrid.DataBind();
RadFilter is only binding those columns which are bind through and ignoring those who are in . Is this a known issue? as I didn't see any thread talking about this problem. Waiting for help immediately.
Regards,
Wasim.
If I am understanding you correctly, you need to add FilterFieldEditors to the RadFilter for any field that is not represented in the DataSource for the grid.
You can add filters dynamically with the following code.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (!IsPostBack)
{
var fieldName = "myDynamicFilterField";
var friendlyName = "Friendly Dynamic Field";
var newTextFieldEditor = new RadFilterTextFieldEditor();
filter.FieldEditors.Add(newTextFieldEditor);
newTextFieldEditor.FieldName = fieldName; // name filter will used for filter exressions
newTextFieldEditor.DisplayName = friendlyName; // name use will see when they selected a field to filter
// ** Repeat for all dynamic fields **
}
}
I was able to get a working version using auto generated columns and custom added columns, but ran into many other problems. I ended up just dynamically creating all the filter fields (as shown above) from the data source and applying the filter expression to the grid.

Resources