Filtering Data on a DevExpress GridView - vb.net

I am an MVC person, and have minimal experience with WebForms, but now I am having to add some functionality to a legacy VB.NET WebForms application.
So the application is using DevExpress Grids, and it displays a really long grid view on the page where one of the columns has the following:
The extra functionality that I am asked to add is a filter where the user can say:
I only want to see the rows where the on-load radio button selected is Print (or one of the other two actions).
So I went to the bottom of the grid and created the following:
My thinking was, the user can come to this drop down and selected what he or she wants to filter on for radio button actions.
DevExpress GridView Code
<dx:ASPxGridView ID="GridView1" runat="server" Theme="Office2010Blue" KeyFieldName="ID" AutoGenerateColumns="False" DataSourceID="ObjectDataSource1" Width="3200px">
<Columns>
<!-- Many more columns go here -->
<dx:GridViewDataColumn Caption="" VisibleIndex="29" Name="decision" Width="150px">
<HeaderTemplate>
<asp:LinkButton runat="server" ID="lnkPrint" OnClick="SelectPrintAll">Print All</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkEmail" OnClick="SelectEmailAll">Email All</asp:LinkButton>
<asp:LinkButton runat="server" ID="lnkIgnore" OnClick="SelectIgnoreAll">Ignore All</asp:LinkButton>
</HeaderTemplate>
<DataItemTemplate>
<asp:UpdatePanel runat="server" ID="upRadDecision" UpdateMode="Conditional">
<ContentTemplate>
<dx:ASPxRadioButtonList ID="radDecision" runat="server" RepeatDirection="Horizontal"
OnSelectedIndexChanged="StoreDecisionForRow" AutoPostBack="True" Height="15px"
OnDataBinding="BindDecisionRadioButton">
<Border BorderStyle="None"></Border>
<Paddings Padding="0"></Paddings>
<Items>
<dx:ListEditItem Text="Print" Value="Print" />
<dx:ListEditItem Text="Email" Value="Email" />
<dx:ListEditItem Text="Ignore" Value="Ignore" />
</Items>
</dx:ASPxRadioButtonList>
</ContentTemplate>
</asp:UpdatePanel>
</DataItemTemplate>
<Settings HeaderFilterMode="CheckedList"></Settings>
</dx:GridViewDataColumn>
</Columns>
<!-- Stylres -->
<Styles>
<AlternatingRow Enabled="true" />
</Styles>
<!-- Settings -->
<Settings ShowFilterRow="True" ShowFilterRowMenu="true" ShowFilterBar="Auto" ShowHeaderFilterButton="true" ShowGroupPanel="True" ShowFooter="True" />
<SettingsBehavior AllowSelectByRowClick="False" />
<SettingsBehavior AllowSelectSingleRowOnly="False" />
<SettingsBehavior ProcessSelectionChangedOnServer="true" />
<SettingsPager Mode="ShowAllRecords" />
<GroupSummary>
<dx:ASPxSummaryItem SummaryType="Count" />
</GroupSummary>
</dx:ASPxGridView>
I have added a click handler to my filter button, and the code is like so:
Private Sub btnFilterDefaults_Click(sender As Object, e As EventArgs) Handles btnFilterDefaults.Click
Dim filterOn As String = ddDefaultsFilterOption.SelectedValue
'Code Handling the Filtering.
GridView1.filter
For rowIndex As Integer = 0 To GridView1.VisibleRowCount - 1
Dim datarow = GridView1.GetDataRow(rowIndex)
Dim radDecision As ASPxRadioButtonList = CType(GridView1.FindRowCellTemplateControl(rowIndex, Nothing, "radDecision"), ASPxRadioButtonList)
Dim decision As String = ""
If radDecision.Value Is Nothing then Continue For
decision = radDecision.Value.ToString()
If decision.Contains(filterOn) Then
datarow.?? <<<<< no option to hide row here!!! :/
End If
Next
End Sub
I was hoping that when I got hold of the data row, I'd be able to hide it, but there is no such option!

I think the issue is you're trying to apply a visible trait to a datarow. What you want to do is use GridViewRow instead. It's the presentation object. Sorry I don't have an example for you but here is a link to msdn for it

Did you try to use HeaderFilterMode for your GridView? This function started from 12 DevExpress version, as I remember. Look at the example below, how you can enable it.
<dx:GridViewDataColumn Caption="" VisibleIndex="29" Name="decision" Width="150px">
...
<Settings HeaderFilterMode="CheckedList" />
</dx:GridViewDataColumn>
If you have older version or you need completely another functionality, you can create your own custom template for filter column. Look at the example on c# below
public class FilterLookupTemplate : ITemplate
{
private const string FormatFilterValue = "FilterLookupTemplateValue_{0}";
public string ClientIdLookup { get; private set; }
public string FieldName { get; set; }
public string DataSourceID { get; set; }
public ASPxGridView GridView { get; set; }
#region ITemplate Members
/// <summary>
/// Initialization template
/// </summary>
public void Init()
{
(GridView != null).Ensure<ArgumentException>("There didn't passed reference to grid view!");
if (!GridView.IsClientSideAPIEnabled() || String.IsNullOrEmpty(GridView.ClientInstanceName))
{
GridView.ClientInstanceName = GridView.ID;
}
var column = GridView.Columns[FieldName] as GridViewDataColumn;
(column != null).Ensure<ArgumentException>("There is error to get column by name!");
column.Settings.ShowFilterRowMenu = DefaultBoolean.False;
GridView.AutoFilterCellEditorCreate += OnAutoFilterCellEditorCreate;
GridView.AutoFilterCellEditorInitialize += OnAutoFilterCellEditorInitialize;
GridView.ProcessColumnAutoFilter += OnProcessColumnAutoFilter;
}
/// <summary>
/// Creating filter dropdown control
/// </summary>
/// <param name="sender">Event sender</param>
/// <param name="e">Event arguments</param>
private void OnAutoFilterCellEditorCreate(object sender, ASPxGridViewEditorCreateEventArgs e)
{
if (e.Column.FieldName.Equals(FieldName))
{
var dde = new DropDownEditProperties { EnableClientSideAPI = true, DropDownWindowTemplate = this };
e.EditorProperties = dde;
}
}
/// <summary>
/// Initializing filter dropdown control
/// </summary>
/// <param name="sender">Event sender</param>
/// <param name="e">Event arguments</param>
private void OnAutoFilterCellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e)
{
if (e.Column.FieldName.Equals(FieldName))
{
var editor = e.Editor as ASPxDropDownEdit;
(editor != null).Ensure<ArgumentException>("There wasn't passed reference to the drop down editor!");
editor.ReadOnly = true
}
}
/// <summary>
/// Processing column filtering
/// </summary>
/// <param name="sender">Event sender</param>
/// <param name="e">Event arguments</param>
private void OnProcessColumnAutoFilter(object sender, ASPxGridViewAutoFilterEventArgs e)
{
var session = GridView.Page.Session;
if (e.Kind == GridViewAutoFilterEventKind.CreateCriteria)
{
session[String.Format(FormatFilterValue, e.Column.FieldName)] = e.Value;
if (e.Column.FieldName.Equals(FieldName) && !String.IsNullOrEmpty(e.Value))
{
var values = e.Value.Split(new[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
if (values.Length > 0)
{
var action = new Func<string, string, FunctionOperator>((name, value) =>
new FunctionOperator(FunctionOperatorType.Contains, new OperandProperty(name), new OperandValue(value)));
if (values.Length > 1)
{
var group = new GroupOperator(GroupOperatorType.Or);
group.Operands.AddRange(values.Select(v => action(e.Column.FieldName, v)).ToArray());
e.Criteria = group;
}
else
{
e.Criteria = action(e.Column.FieldName, values[0]);
}
}
}
}
else
{
if (session[String.Format(FormatFilterValue, e.Column.FieldName)] != null)
{
e.Value = session[String.Format(FormatFilterValue, e.Column.FieldName)].ToString();
}
}
}
/// <summary>
/// Rendering loolup template controls
/// </summary>
/// <param name="container">Container of date range template</param>
public void InstantiateIn(Control container)
{
(GridView != null).Ensure<ArgumentException>("There didn't passed reference to grid view!");
var table = new Table { Width = new Unit(200, UnitType.Pixel) };
container.Controls.Add(table);
var row = new TableRow();
table.Rows.Add(row);
var cell = new TableCell();
row.Cells.Add(cell);
var lbl = new ASPxLabel { ID = "lblSelect", Text = MessageResources.FilterLookupTemplate_SelectLabelText };
cell.Controls.Add(lbl);
cell = new TableCell();
row.Cells.Add(cell);
var lookup = new ASPxGridLookup
{
ID = GridView.ID + "lookupValues",
EnableClientSideAPI = true,
Width = new Unit(100, UnitType.Percentage),
SelectionMode = GridLookupSelectionMode.Multiple
};
lookup.GridView.Width = new Unit(100, UnitType.Percentage);
lookup.GridView.DataSourceID = DataSourceID;
lookup.GridView.KeyFieldName = "id";
lookup.GridView.Columns.Add(new GridViewCommandColumn { ShowSelectCheckbox = true, AllowDragDrop = DefaultBoolean.False });
var nameColumn = new GridViewDataTextColumn { FieldName = "name" };
nameColumn.Settings.AllowDragDrop = DefaultBoolean.False;
nameColumn.Settings.AllowGroup = DefaultBoolean.False;
nameColumn.Settings.AllowHeaderFilter = DefaultBoolean.False;
nameColumn.Settings.AllowSort = DefaultBoolean.False;
lookup.GridView.Columns.Add(nameColumn);
lookup.EnableClientSideAPI = true;
cell.Controls.Add(lookup);
ClientIdLookup = lookup.ClientID;
row = new TableRow();
table.Rows.Add(row);
cell = new TableCell { ColumnSpan = 2 };
row.Cells.Add(cell);
var lnk = new ASPxHyperLink { Text = MessageResources.FilterLookupTemplate_ApplyLinkText, NavigateUrl = "#" };
lnk.ClientSideEvents.Click =
String.Format("function (s, e) {{ {0}.HideDropDown(); ApplyLookupFilter({0}, {1}, '{2}', {3}); }}",
container.NamingContainer.NamingContainer.ClientID,
GridView.ClientInstanceName,
FieldName,
ClientIdLookup);
cell.Controls.Add(lnk);
container.Controls.Add(table);
}
#endregion
}
and then register it for your grid view. ReportsCustomerDataSource is a LINQ data source control.
public partial class YourPage: Page
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
new FilterLookupTemplate { FieldName = "ReportCustomers", DataSourceID = ReportsCustomerDataSource.ID, GridView = _gridView }.Init();
}
}
On the form it will be look like that

Related

Make Swagger output the description of an IRouteConstraint

I have a route with a custom IRouteConstraint.
Swagger generates the parameter section but the description field is always empty. For other parameters I get the description from the XML comments correctly.
The only workaround I found so far is adding a Operation filter and set the description there for the
foreach ( var parameter in operation.Parameters.OfType<NonBodyParameter>() )
{
if (parameter.Name == RouteConstraint.Name)
{
parameter.Description = GetConstraintDescription();
}
Any way to instruct swagger to get the description from the XML comments for IRouteConstraints.
I'm afraid that the only "easy way" is what you already implemented (an Operation filter)
I was looking at the XML description that your project outputs
<?xml version="1.0"?>
<doc>
<assembly>
<name>SwaggerWeb</name>
</assembly>
<members>
<member name="M:SwaggerWeb.Controllers.ValuesController.Get(System.Int32)">
<summary> Get by ID </summary>
<param name="id">The value ID</param>
<returns></returns>
</member>
<member name="T:SwaggerWeb.SectorRouteConstraint">
<summary> Sector constraint </summary>
</member>
</members>
</doc>
You can try make your filter a bit more generic and fish the description out of the XML, but other than that I do not see any other way.
My current solution is this class, based on the Swashbuckle XmlCommentsOperationFilter.
public class RouteConstraintXmlDocsOperationFilter:IOperationFilter
{
private readonly XPathNavigator _xmlNavigator;
private const string MemberXPath = "/doc/members/member[#name='{0}']";
private const string SummaryXPath = "summary";
public RouteConstraintXmlDocsOperationFilter(string filePath)
{
XPathDocument xmlDoc = new XPathDocument(filePath);
_xmlNavigator = xmlDoc.CreateNavigator();
}
public void Apply(Operation operation, OperationFilterContext context)
{
ApplyConstraintsXmlToActionParameters(operation.Parameters, context.ApiDescription);
}
private void ApplyConstraintsXmlToActionParameters(IList<IParameter> parameters, ApiDescription apiDescription)
{
var nonBodyParameters = parameters.OfType<NonBodyParameter>();
foreach (var parameter in nonBodyParameters)
{ // Check for a corresponding action parameter?
var actionParameter = apiDescription.ParameterDescriptions.FirstOrDefault(p =>
parameter.Name.Equals(p.Name, StringComparison.OrdinalIgnoreCase));
if (actionParameter == null) continue;
if (!actionParameter.RouteInfo.Constraints.Any()) continue;
var constraintType = actionParameter.RouteInfo.Constraints.FirstOrDefault().GetType();
var commentIdForType = XmlCommentsIdHelper.GetCommentIdForType(constraintType);
var constraintSummaryNode = _xmlNavigator
.SelectSingleNode(string.Format(MemberXPath, commentIdForType))
?.SelectSingleNode(SummaryXPath);
if (constraintSummaryNode != null)
{
parameter.Description = XmlCommentsTextHelper.Humanize(constraintSummaryNode.InnerXml);
}
}
}
}
To set it up:
services.AddSwaggerGen(o =>
{
var fileName = GetType().GetTypeInfo().Module.Name.Replace(".dll", ".xml").Replace(".exe", ".xml");
o.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, fileName));
o.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });
o.OperationFilter<RouteConstraintXmlDocsOperationFilter>(Path.Combine(AppContext.BaseDirectory, fileName));
})

Dropdownlist just retrieving objects and dynamically show in Ajax Text box

So Im starting as a new ASP Developer (been using Java for a bit, but now project demands ASP), so bare a little with my ignorance :( .
What I am trying to do is create a dynamic dropdown list from a table I got in SQL SERVER and depending on what you choose on the list show the information on the txt editor (In theory shouldnt be so hard, but since I just started, it just does not seem so easy). I created the entity for it, the data for it and the bussiness logic for it and the interconnection (It is already reading and retrieving from the DB, but just a list). Here is, what I have doing so hard.
Entity.Messages
public class Messages
{
public int id { get; set; }
public string title { get; set; }
public string subject { get; set; }
public string body { get; set; }
public string createdBy { get; set; }
public Messages()
{
id = 0;
title = "";
subject = "";
body = "";
createdBy = "";
}
public Messages(int idMessages)
{
idMessages = id;
title = "";
subject = "";
body = "";
createdBy = "";
}
}
}
Data.Messages
public class Messages : Data
{
public Messages() : base()
{
}
public List<Entity.Messages> GetAll()
{
List<Entity.Messages> message = new List<Entity.Messages>();
//SQL Command para llamar el stored procedure
SqlCommand comando = new SqlCommand("dbo.[Messages_GetAll]", base.Db);
//Ejecuta consulta
DataTable dtItem = base.Execute(comando);
//Transforma el Datatable en una lista de proyectos.
foreach (DataRow dr in dtItem.Rows)
message.Add(GetFromDataRow(dr));
return message;
}
public Entity.Messages GetById(int id)
{
Entity.Messages m = new Entity.Messages();
//SQL Command para llamar el stored procedure
SqlCommand comando = new SqlCommand("dbo.[Messages_GetById]", base.Db);
//parametros del store procedure
SqlParameter spKey = new SqlParameter("#Id", System.Data.SqlDbType.Int);
spKey.Value = id;
comando.Parameters.Add(spKey);
//Ejecuta consulta
DataTable dt = base.Execute(comando);
if (dt.Rows.Count > 0)
m = GetFromDataRow(dt.Rows[0]);
return m;
}
private ASF.HC.JobApplication.Entity.Messages GetFromDataRow(DataRow dr)
{
Entity.Messages m = new Entity.Messages();
m.id = dr["Id"] == DBNull.Value ? -1 : int.Parse(dr["Id"].ToString());
m.title = dr["Title"] == DBNull.Value ? "" : dr["Title"].ToString();
m.subject = dr["Subject"] == DBNull.Value ? "" : dr["Subject"].ToString();
m.body = dr["Body"] == DBNull.Value ? "" : dr["Body"].ToString();
m.createdBy = dr["createdBy"] == DBNull.Value ? "" : dr["createdBy"].ToString();
return m;
}
}
BO.Messages
public class Messages
{
public Entity.Messages GetByID(int id)
{
Data.Messages oMessage = new Data.Messages();
return oMessage.GetById(id);
}
public List<Entity.Messages> GetAll()
{
Data.Messages oMessage = new Data.Messages();
return oMessage.GetAll();
}
And where Im trying to display it, I see the DropDownList and well I see the List with the objects, but I want to display is the title.
MEssage.aspx
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Messages.aspx.cs" Inherits="ASF.HC.JobApplication.Admin.Messages" %>
<%# Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="ajaxToolkit" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Messages</h2>
<asp:ScriptManager ID="ScriptManager2" runat="server"></asp:ScriptManager>
<legend>Pick the template to use:</legend>
<asp:dropdownlist id ="ddlTemplate" runat ="server" Height="38px" Width="397px">
<asp:listitem value ="1"> Juan Valdez </asp:listitem >
<asp:listitem Value ="2"> Querido bebe</asp:listitem>
</asp:dropdownlist >
<p> </p>
<asp:TextBox ID ="txtDetails" runat="server" Width="600px" Height="300px" Visible="true" ></asp:TextBox>
<ajaxToolkit:HtmlEditorExtender ID="TextBox1_HtmlEditorExtender" runat="server" TargetControlID="txtDetails"
EnableSanitization="false" DisplaySourceTab="true" >
</ajaxToolkit:HtmlEditorExtender>
</asp:Content>
Messages.aspx.cs
public partial class Messages : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
loadList();
}
public void loadList()
{
BO.Messages template = new BO.Messages();
ddlTemplate.DataSource = template.GetAll();
ddlTemplate.DataBind();
}
}
}
Im trying to go step by step, but first I wanna see the value and not the objects, and according to what I choose to see the Body field Displayed on the text field on Ajax. But first, and most importantly, show the title field on the dropdownlist :(
EDIT: So I got to show the Title instead of all the object. But now, do you guys know any way to as soon as I choose the title, to have it displayed on the Text from ajax? Like dynamically? Any point would be greatly appreciated.
Any help or pointer would be greatly appreciated.
Thanks!
Apparently, all I needed was to map the datavalue and datatext field.

Templated control in ektron

I have tried to retrieve the taxonomy list using taxonomy tree, in edit i am selecting the taxonomy and getting TaxonomyID,by using the taxonomyID i want to display the data using taxonomy filters using templated control.I am unable to retrive the data.I am attaching HTML and Code what i have done,So please help me out for the solution.
<asp:View ID="View" runat="server">
<asp:Label ID="lblID" runat="server"></asp:Label>
<CMS:Directory CssClass="taxList" ID="TaxonomySummary1" EnableAjax="true" runat="server"
EnablePaging="false" />
<ektron:ContentModelSource ID="cntModelSourcs" runat="server" OrderByField="DateCreated"
OrderByDirection="Descending">
<TaxonomyFilters>
<ektron:ContentTaxonomyFilter Operator="Contains" ID="taxFilter" runat="server" />
</TaxonomyFilters>
<ContentFilters>
<ektron:ContentFilter Field="Id" Operator="EqualTo" Value="" />
</ContentFilters>
</ektron:ContentModelSource>
<ektron:ContentView ID="ContentView1" runat="server" ModelSourceID="cntModelSourcs"
EktronCustomTemplate="Ektron_ContentList_Template" >
</ektron:ContentView>
</asp:View>
enter code here
_edit" class="TSWidget">
<div class="ByTaxonomy TSTabPanel">
<div style="height: 150px; overflow: auto;">
<UC:TaxonomyTree ID="TaxonomyTree1" runat="server" />
</div>
<hr />
</div>
<div class="ByProperty TSTabPanel">
<table style="width: auto;">
<tr>
<td class="label">
<%=m_refMsg.GetMessage("lbl taxonomy id:")%>
</td>
<td>
<asp:TextBox ID="taxonomyid" CssClass="folderid" runat="server" Style="width: auto;"></asp:TextBox>
</td>
</tr>
<tr>
<td class="label">
<%=m_refMsg.GetMessage("lbl taxonomy path:")%>
</td>
<td>
<asp:Label ID="taxonomypath" CssClass="taxonomypath" runat="server"></asp:Label>
</td>
</tr>
</table>
</div>
<div class="TSEditControls">
<asp:Button ID="CancelButton" CssClass="TSCancel" runat="server" Text="Cancel" OnClick="CancelButton_Click" />
<asp:Button ID="SaveButton" CssClass="TSSave" runat="server" OnClick="SaveButton_Click" Text="Save" />
</div>
</div>
</asp:View>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Ektron.Cms;
using Ektron.Cms.Widget;
using Ektron.Cms.Common;
using Ektron.Cms.API;
using Ektron.Cms.Organization;
using Ektron.Cms.Framework.Organization;
using System.Text;
using Ektron.Cms.Search.Expressions;
using Ektron.Cms.Search;
using Ektron.Cms.Framework;
public partial class widgets_Content_TaxonomyFilter : System.Web.UI.UserControl,IWidget
{
# region Properties
protected string appPath = "";
private Ektron.Cms.CommonApi _commonAPI = new CommonApi();
private long _taxonomyid;
public string TaxonomySelected = "selected";
public string PropertySelected = "selected";
public string m_strTaxonomyPath = "/";
private string _taxonomypath;
[WidgetDataMember(0)]
public long TaxonomyId { get { return _taxonomyid; } set { _taxonomyid = value; } }
[WidgetDataMember("")]
public string TaxonomyPaths { get { return _taxonomypath; } set {
_taxonomypath = value; } } private IWidgetHost _host;
protected ContentAPI m_refContentApi = new ContentAPI();
protected EkMessageHelper m_refMsg;
#endregion
# region Page Load
protected void Page_Load(object sender, EventArgs e)
{
taxFilter.Value = TaxonomyId.ToString();
ContentView1.DataBind();
}
#endregion
#region Page Init
protected void Page_Init(object sender, EventArgs e)
{
m_refMsg = m_refContentApi.EkMsgRef;
CancelButton.Text = m_refMsg.GetMessage("btn cancel");
SaveButton.Text = m_refMsg.GetMessage("btn save");
_host = Ektron.Cms.Widget.WidgetHost.GetHost(this);
_host.Title = "Templated Control";
_host.Edit += new EditDelegate(EditEvent);
_host.Maximize += new MaximizeDelegate(delegate() { Visible = true; });
_host.Minimize += new MinimizeDelegate(delegate() { Visible = false; });
_host.Create += new CreateDelegate(delegate() { EditEvent(""); });
_host.ExpandOptions = Expandable.ExpandOnEdit;
appPath = _commonAPI.AppPath;
Load += new EventHandler(delegate(object PreRenderSender, EventArgs Evt) { if
(ViewSet.GetActiveView() != Edit) SetTaxonomySummary(); });
ViewSet.SetActiveView(View);
}
protected void SetTaxonomySummary()
{
if (TaxonomyId > 0)
{
lblID.Text = Convert.ToString(taxFilter.Value);
}
}
#endregion
#region EditEvent
void EditEvent(string settings)
{
try
{
string sitepath = _commonAPI.SitePath;
string webserviceURL = sitepath + "widgets/taxonomysummary/TSHandler.ashx";
JS.RegisterJSInclude(this, JS.ManagedScript.EktronJS);
Ektron.Cms.API.JS.RegisterJSInclude(this,
Ektron.Cms.API.JS.ManagedScript.EktronJQueryClueTipJS);
JS.RegisterJSInclude(this, JS.ManagedScript.EktronScrollToJS);
JS.RegisterJSInclude(this, sitepath + "widgets/taxonomysummary/behavior.js",
"TaxonomySummaryWidgetBehaviorJS");
if (TaxonomyId > 0)
{
TaxonomySelected = "";
JS.RegisterJSBlock(this, "Ektron.PFWidgets.TaxonomySummary.webserviceURL =
\"" + webserviceURL + "\";
Ektron.PFWidgets.TaxonomySummary.setupAll();
Ektron.PFWidgets.TaxonomySummary.SetTabs.init()
; ", "EktronPFWidgetsTSInit");
}
else
{
PropertySelected = "";
JS.RegisterJSBlock(this, "Ektron.PFWidgets.TaxonomySummary.webserviceURL =
\"" + webserviceURL + "\";
Ektron.PFWidgets.TaxonomySummary.setupAll(); ", "EktronPFWidgetsTSInit");
}
Css.RegisterCss(this, sitepath + "widgets/taxonomysummary/TSStyle.css",
"TSWidgetCSS");
ViewSet.SetActiveView(Edit);
//set taxonomy path
Ektron.Cms.API.Content.Taxonomy _apiTaxonomy = new
Ektron.Cms.API.Content.Taxonomy();
Ektron.Cms.TaxonomyRequest taxRequest = new Ektron.Cms.TaxonomyRequest();
taxRequest.TaxonomyId = TaxonomyId;
taxRequest.IncludeItems = false;
taxRequest.TaxonomyLanguage = _apiTaxonomy.ContentLanguage;
Ektron.Cms.TaxonomyData taxData = _apiTaxonomy.LoadTaxonomy(ref taxRequest);
if (!(taxData == null || string.IsNullOrEmpty(taxData.Path)))
{
taxonomypath.Text = taxData.Path;
m_strTaxonomyPath = taxData.Path;
}
else
{
m_strTaxonomyPath = "";
}
}
catch (Exception e)
{
ViewSet.SetActiveView(View);
}
}
#endregion
#region Button Events
protected void CancelButton_Click(object sender, EventArgs e)
{
ViewSet.SetActiveView(View);
}
protected void SaveButton_Click(object sender, EventArgs e)
{
int taxID = Convert.ToInt32(taxonomyid.Text);
TaxonomyId = taxID;
taxFilter.Value = TaxonomyId.ToString();
SetTaxonomySummary();
_host.SaveWidgetDataMembers();
ViewSet.SetActiveView(View);
}
#endregion
public EventArgs e { get; set; }
}
If I understand your question correctly, you have the taxonomy id and want to display all the content within that taxonomy. If that is not what you are after, then please clarify your question, and I'll try to help as best I can.
I find that the added baggage that comes along with a widget can sometimes make it hard to test for correct API and server control usage. For that reason, I'd recommend starting off with a simple ASPX page.
<ektron:ContentModelSource ID="contentModelSource" runat="server">
</ektron:ContentModelSource>
<ektron:ContentView ID="ContentView1" runat="server" ModelSourceID="contentModelSource" EktronCustomTemplate="Ektron_ContentList_Template">
</ektron:ContentView>
Normally, the examples you'll find for the templated server controls show the declarative syntax for setting the filters, where you put them right into the ASPX markup - right inside the ContentModelSource control. Something like:
<TaxonomyFilters>
<ektron:ContentTaxonomyFilter Field="Id" Operator="EqualTo" Value="208" />
</TaxonomyFilters>
(More examples here and here.)
But for what it sounds like you want to accomplish, you need to define the filters via code. This code does just that:
protected long TaxonomyId
{
get
{
long id;
long.TryParse(Request.QueryString["id"], out id);
return id;
}
}
protected bool IsRecursive
{
get
{
bool recursive;
bool.TryParse(Request.QueryString["recursive"], out recursive);
return recursive;
}
}
protected void Page_Init(object sender, EventArgs e)
{
if (TaxonomyId > 0)
{
if (IsRecursive)
{
var tm = new TaxonomyManager();
var td = tm.GetItem(TaxonomyId);
if (td != null)
{
var pathFilter = new ContentTaxonomyFilter();
pathFilter.Field = ContentTaxonomyProperty.Path;
pathFilter.Operator = CriteriaFilterOperator.StartsWith;
pathFilter.Value = td.Path;
contentModelSource.TaxonomyFilters.Add(pathFilter);
}
}
else
{
var filter = new ContentTaxonomyFilter();
filter.Field = ContentTaxonomyProperty.Id;
filter.Value = TaxonomyId.ToString();
filter.Operator = CriteriaFilterOperator.EqualTo;
contentModelSource.TaxonomyFilters.Add(filter);
}
}
}
A couple of things to note:
The TaxonomyId is a property. I did this so that there would be an easy point of comparison between this simple ASPX page and a custom widget where your property would be decorated with the WidgetDataMember attribute.
The code is in the Page_Init event handler. That is important. Page_Load is too late in the page's lifecycle. I assume this would also be true in the context of a widget.
My code for when IsRecursive == true is not necessarily optimized. You could get reasonable performance by turning on caching in the FrameworkAPI, but the idea of calling the api to get the taxonomyData and then using that to set the filter for the content seems a little off. Ideally, the ContentTaxonomyFilter would have a "Recursive" property.

Parameterized Constructor for WinRT UserControl

I am trying to create a custom Pushpin for Bing Maps in my WinRT application. My problem is that I need a reference to the actual Map from my page in order to pin the icons correctly in my userControl. So for example this is my DataTemplate which gets bound to the map and works fine for the normal pushpins. For my custom userControl to position correctly I need a reference to the parent Map in the userControl.
This is my XAML:
<m:MapItemsControl x:Name="Pushpinss" ItemsSource="{Binding InventoryItems}">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<!-- NORMAL PUSHPIN WORKS -->
<m:Pushpin>
<m:MapLayer.Position>
<m:Location Latitude="{Binding WarehouseLatitude}"
Longitude="{Binding WarehouseLongitude}" />
</m:MapLayer.Position>
</m:Pushpin>
<!-- CUSTOM CONTROL DISPLAYS BUT DOES NOT POSITION CORRECTLY BECAUSE I NEED A REFERENCE TO THE MAP-->
<View:GPSIcon Latitude="{Binding WarehouseLatitude}"
Longitude="{Binding WarehouseLongitude}"
Radius="100000"/>
<x:Arguments>
</x:Arguments>
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
This is my custom control:
public sealed partial class GPSIcon : UserControl
{
private Map _map;
private const double EARTH_RADIUS_METERS = 6378137;
public GPSIcon(Map map)
{
this.InitializeComponent();
_map = map;
_map.ViewChanged += (s, e) =>
{
UpdateAccuracyCircle();
};
}
public static readonly DependencyProperty LatitudeProperty =
DependencyProperty.Register("Latitude", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));
public static readonly DependencyProperty LongitudeProperty =
DependencyProperty.Register("Longitude", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));
public static readonly DependencyProperty RadiusProperty =
DependencyProperty.Register("Radius", typeof(double), typeof(GPSIcon), new PropertyMetadata(0));
public double Latitude
{
get { return (double)GetValue(LatitudeProperty); }
set { SetValue(LatitudeProperty, value); }
}
public double Longitude
{
get { return (double)GetValue(LongitudeProperty); }
set { SetValue(LongitudeProperty, value); }
}
/// <summary>
/// Radius in Metres
/// </summary>
public double Radius
{
get { return (double)GetValue(RadiusProperty); }
set
{
SetValue(RadiusProperty, value);
UpdateAccuracyCircle();
}
}
private void UpdateAccuracyCircle()
{
if (_map != null && Radius >= 0)
{
double groundResolution = Math.Cos(_map.Center.Latitude * Math.PI / 180) * 2 * Math.PI * EARTH_RADIUS_METERS / (256 * Math.Pow(2, _map.ZoomLevel));
double pixelRadius = Radius / groundResolution;
AccuracyCircle.Width = pixelRadius;
AccuracyCircle.Height = pixelRadius;
AccuracyCircle.Margin = new Thickness(-pixelRadius / 2, -pixelRadius / 2, 0, 0);
}
}
}
Is this possible at all? I have also tried using the x:Arguments directive as described here:
http://msdn.microsoft.com/en-us/library/ee795382.aspx
Thanks
UPDATE 1
Do following changes
1) Add empty constructor.
public GPSIcon()
{
this.InitializeComponent();
}
2) Declare DP of type Map
public Map MyMap
{
get { return (Map)GetValue(MyMapProperty); }
set { SetValue(MyMapProperty, value); }
}
public static readonly DependencyProperty MyMapProperty =
DependencyProperty.Register("MyMap", typeof(Map), typeof(GPSIcon), new PropertyMetadata(default(Map), OnMapSet));
private static void OnMapSet(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
_map = ((GPSIcon)(d)).MyMap;
_map.ViewChanged += (ss, ee) =>
{
((GPSIcon)(d)).UpdateAccuracyCircle();
};
}
3) Pass Map object like this in XAML
<m:Map x:Name="objMap">
<m:MapItemsControl x:Name="Pushpinss" ItemsSource="{Binding InventoryItems}">
<m:MapItemsControl.ItemTemplate>
<DataTemplate>
<View:GPSIcon Latitude="{Binding WarehouseLatitude}"
Longitude="{Binding WarehouseLongitude}"
Radius="100000"
MyMap="{Binding ElementName=objMap}"/>
</DataTemplate>
</m:MapItemsControl.ItemTemplate>
</m:MapItemsControl>
</m:Map>
Declare one more dependency property of type Map and then you should pass current map instance as a value of that DP in <View:GPSIcon ... />
Simply, you need to follow the same logic as how to Pass parameter to constructor from xaml in Silverlight
To get your custom UIElement to position properly on the map what you can do instead of doing this in code is simply set the position of the UIElement the same way you set the position of a pushpin.
For example:
<View:GPSIcon Radius="100000">
<m:MapLayer.Position>
<m:Location Latitude="{Binding WarehouseLatitude}"
Longitude="{Binding WarehouseLongitude}" />
</m:MapLayer.Position>
</View:GPSIcon>

Adding LinqDataSource Where Parameters in Code-Behind

Reading simple table using LinqDataSource. Table name is ZipCode with three columns: ZipCode, City, State). Read works fine with no filter, but when I add "Where" parameters to LinqDataSource, it fails in the GridView databind with an error, "No property or field "CityValue" exists in the type "ZipCode".
ASPX:
<asp:GridView ID="grdLDS" runat="server" AllowPaging="True" AllowSorting="True"
DataSourceID="ldsData" AutoGenerateColumns="False" >
<Columns>
<asp:BoundField DataField="ZIPCODE1" HeaderText="ZipCode" SortExpression="ZIPCODE1" />
<asp:BoundField DataField="CITY" HeaderText="City" SortExpression="CITY" />
<asp:BoundField DataField="STATE" HeaderText="State" SortExpression="STATE" />
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="ldsData" runat="server" ContextTypeName="LinqLayer.CommonDataDataContext"
TableName="ZipCodes" OnSelecting="ldsData_Selecting" OnSelected="ldsData_Selected" >
</asp:LinqDataSource>
Code-Behind:
protected void ldsData_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
if (!cbxLDS.Checked)
{
e.Cancel = true;
return;
}
ldsData.WhereParameters.Clear();
StringBuilder where = new StringBuilder();
if (!string.IsNullOrEmpty(txtFilterByZip.Text))
{
where.Append("ZIPCODE1.StartsWith(#ZipValue)");
ldsData.WhereParameters.Add("#ZipValue", txtFilterByZip.Text);
}
if (!string.IsNullOrEmpty(txtFilterByCity.Text))
{
if (where.Length > 0) where.Append(" & ");
where.Append("CITY.StartsWith(#CityValue)");
ldsData.WhereParameters.Add("#CityValue", txtFilterByCity.Text);
}
if (!string.IsNullOrEmpty(txtFilterByState.Text))
{
if (where.Length > 0) where.Append(" & ");
where.Append("STATE.StartsWith(#StateValue)");
ldsData.WhereParameters.Add("#StateValue", txtFilterByState.Text);
}
ldsData.Where = where.ToString();
}
protected void ldsData_Selected(object sender, LinqDataSourceStatusEventArgs e)
{
LDSRowCount = e.TotalRowCount;
}
private int RefreshLDSData()
{
grdLDS.DataBind(); // <== CODE FAILS ON THIS LINE
return LDSRowCount;
}
private IEnumerable<ZipCode> FilterLDSData(IEnumerable<ZipCode> rows)
{
return rows;
}
you can try like this in where parameter with linqdatasource..
NOte :this is just example how to use the where parameter using linqdatasource...
public void LinqDataSource1_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
var db = new MyDataContext())
var subjectFilter = e.WhereParameters("Subject");
var reporters = from spName in db.spReporter()
where spName.Subject.Contains(subjectFilter)
select new Reporter(spName.Id, spName.InqDate, spName.Subject);
e.Result = reporters;
}
pls go through this link for more info
Thanks to Andy Robinson, here is the solution:
protected void ldsData_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
if (!cbxLDS.Checked)
{
e.Cancel = true;
return;
}
var dc = new CommonDataDataContext();
var query = dc.ZipCodes.Select(r => new ZipData()
{
ZipCode = r.ZIPCODE1,
City = r.CITY,
State = r.STATE,
});
e.Result = ldsFilter(query);
}
private IQueryable<ZipData> ldsFilter(IQueryable<ZipData> rows)
{
if (!string.IsNullOrEmpty(txtFilterByZip.Text))
{
rows = rows.Where(r => r.ZipCode.StartsWith(txtFilterByZip.Text));
}
if (!string.IsNullOrEmpty(txtFilterByCity.Text))
{
rows = rows.Where(r => r.City.StartsWith(txtFilterByCity.Text));
}
if (!string.IsNullOrEmpty(txtFilterByState.Text))
{
rows = rows.Where(r => r.State.StartsWith(txtFilterByState.Text));
}
return rows;
}
lds_Data_Selecting event provides the structure of the query, and the ldsFilter method does the dynamic filtering. This method must accept and return an iQueryable.