I want to add page number in my application, like 1 2 3 4. My paginated class code is:
public bool HasPreviousPage
{
get
{
return (PageIndex > 0);
}
}
public bool HasNextPage
{
get
{
return (PageIndex+1<TotalPages);
}
}
This code generates link and goto next page, but can't display page number.
Add this property:
public IEnumerable<int> Pages
{
get
{
for(var page=1; page <= TotalPages; pages++)
yield return page;
}
}
You could use it for rendering the pages in your page (i.e. using a repeater).
Hope it helps.
Related
I've added a menu context item to the TreelistEx. This menu item sends a messages that I later catch in a HandleMessage method.
In this method i create a new item ( template type and parent item are given in the source of the treelist field ).
All i need now is a way to ask the user for a name. But i haven't been able to find a simple way to do this.
class MyTreeListEx : TreelistEx, IMessageHandler
{
void IMessageHandler.HandleMessage(Message message)
{
if (message == null)
{ return; }
if (message["id"] == null)
{ return; }
if (!message["id"].Equals(ID))
{ return; }
switch (message.Name)
{
case "treelist:edit":
// call default treelist code
case "mytreelistex:add":
// my own code to create a new item
}
}
}
Does anyone have any suggestions on how to achieve this ?
Edit: added image & code + i'm using Sitecore 8 Update 1
I don't know which version of Sitecore you use but what you can try is SheerResponse.Input method.
You can use it like this:
using Sitecore.Configuration;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor.FieldTypes;
using Sitecore.Web.UI.Sheer;
void IMessageHandler.HandleMessage(Message message)
{
...
case "mytreelistex:add":
Sitecore.Context.ClientPage.Start(this, "AddItem");
break;
}
protected static void AddItem(ClientPipelineArgs args)
{
if (args.IsPostBack)
{
if (!args.HasResult)
return;
string newItemName = args.Result;
// create new item here
// if you need refresh the page:
//SheerResponse.Eval("scForm.browser.getParentWindow(scForm.browser.getFrameElement(window).ownerDocument).location.reload(true)");
}
else
{
SheerResponse.Input("Enter the name of the new item:", "New Item Default Name", Settings.ItemNameValidation,
Translate.Text("'$Input' is not a valid name."), Settings.MaxItemNameLength);
args.WaitForPostBack();
}
}
This code will even validate your new item name for incorrect characters and length.
I am using Lucene.net in my Web App.
Everithing works fine, but now i have to show the number of occurrences of my 'searchstring' in every single document of the hits array.
How can i do this? I use usual BooleanQuery.
That is my search:
BooleanQuery bq = new BooleanQuery();
bq.Add(QueryParser.Parse(Lquery, "", CurIndexDescritor.GetLangAnalizer()), false,false);
BooleanQuery.SetMaxClauseCount(int.MaxValue);
IndexSearcher searcher = new IndexSearcher(indexPath);
Hits hits = (filter != null) ? searcher.Search(bq, filter) : searcher.Search(bq);
for (int i = 0; i < hits.Length(); i++)
{
Document doc = hits.Doc(i);
SearchResultItem MyDb = new SearchResultItem();
MyDb.key = doc.Get(KeyField);
MyDb.score = hits.Score(i);
result.Add(MyDb);
}
Where can i get the number of occurrences?
Thanks!
If you dont want the score back and dont want to order the results using score you could probably build a custom Similarity implementation.
I quickly tested the following code, and it appears to work fine with TermQueries and PhraseQueries, i didnt test more query types tho. A PhraseQuery hit counts as a single occurence.
public class OccurenceSimilarity : DefaultSimilarity
{
public override float Tf(float freq)
{
return freq;
}
public override float Idf(int docFreq, int numDocs)
{
return 1;
}
public override float Coord(int overlap, int maxOverlap)
{
return 1;
}
public override float QueryNorm(float sumOfSquaredWeights)
{
return 1;
}
public override Explanation.IDFExplanation idfExplain(System.Collections.ICollection terms, Searcher searcher)
{
return CACHED_IDF_EXPLAIN;
}
public override Explanation.IDFExplanation IdfExplain(Term term, Searcher searcher)
{
return CACHED_IDF_EXPLAIN;
}
public override float SloppyFreq(int distance)
{
return 1;
}
private static Explanation.IDFExplanation CACHED_IDF_EXPLAIN = new ExplainIt();
private class ExplainIt : Explanation.IDFExplanation
{
public override string Explain()
{
return "1";
}
public override float GetIdf()
{
return 1.0f;
}
}
}
To use it:
Similarity.SetDefault(new OccurenceSimilarity());
This is my database table
DB Table
how to generate a sitemap?
controller is category
action is Id
that is look like it
Page
TreeMenu.cs:
using System;
using System.Collections.Generic;
namespace Pmvc.Models
{
public partial class TreeMenu
{
public int TreeId { get; set; }
public int TreeParentId { get; set; }
public string TreeName { get; set; }
public List<TreeMenu> Children { get; set; }
}
}
StoreDetailsDynamicNodeProvider.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MvcSiteMapProvider.Extensibility;
using Pmvc.Models;
namespace Pmvc
{
public class StoreDetailsDynamicNodeProvider : DynamicNodeProviderBase
{
PMVCEntities pmvcDB = new PMVCEntities();
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
var nodes = new List<DynamicNode>();
foreach (var treemenu in pmvcDB.TreeMenu)
{
nodes.Add(CreateNode(treemenu));
}
return nodes;
}
private DynamicNode CreateNode(TreeMenu treemenu)
{
DynamicNode node = new DynamicNode();
node.Action = "ProductDetails";
node.Controller = "Product";
node.Title = treemenu.TreeName;
if (treemenu.Children != null)
{
foreach (var child in treemenu.Children)
{
node.Children.Add(CreateNode(child)); //This line is wrong!
}
}
return node;
}
}
}
wrong:
'MvcSiteMapProvider.Extensibility.DynamicNode' is not include 'Children' definition,and not find Extension Methods 'Children'
public class StoreDetailsDynamicNodeProvider : DynamicNodeProviderBase
{
PMVCEntities pmvcDB = new PMVCEntities();
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var returnValue = new List<DynamicNode>();
// Create a node for each album
foreach (var treemenu in pmvcDB.TreeMenu)
{
DynamicNode node = new DynamicNode();
node.Action = "ProductDetails";
node.Controller = "Product";
node.Title = treemenu.TreeName;
node.RouteValues.Add("id", treemenu.TreeId);
returnValue.Add(node);
}
// Return
return returnValue;
}
}
This is my table
TreeId TreeParentId TreeName
1 0 Category 1
2 1 Menu Item X
3 1 Menu Item Y
4 1 Menu Item Z
5 0 Category 2
6 5 Other Menu 1
7 5 Other Menu 2
8 0 Empty Category
9 7 Menu Lvl 3
How do I write child node code?
Take a look at the MvcSitemap provider. It's pretty easy to write a dynamic provider that reads from your database.
Edit - did you read the documentation or attempt to implement anything? Copied almost verbatim from their site:
Within the sitemap config file, add the dynamic node where appropriate:
<mvcSiteMapNode
title="Details"
action="Details"
dynamicNodeProvider="MyProjectName.MyDynamicNodeProvider, MyProjectName" />
Then, write the actual node provider:
public class MyDynamicNodeProvider
: DynamicNodeProviderBase
{
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var returnValue = new List<DynamicNode>();
// ... Here, get values from your database and build up
// the list of nodes. They can be in a tree structure
// too since it appears that's how your data is - just
// build the nodes in that way with sub-lists.
// Return
return returnValue;
}
}
And that's it.
Edit 2 - addressing other answer.
The code that you provided flattens the tree structure. In your original post you showed that you are already able to print the tree structure. Whatever code you had in your view, you can apply the same principles of a depth-first traversal.
Just in case that was a mockup and not actual code, here's some quick psuedo code to demonstrate an depth-first traversal.
public override IEnumerable<DynamicNode> GetDynamicNodeCollection()
{
// Build value
var nodes = new List<DynamicNode>();
// Get all categories without parents.
var rootCategories = db.GetRootCategories();
// Loop all root level categories, creating a node for each and adding
// to the return value.
foreach (var category in rootCategories)
{
nodes.Add(CreateNode(category));
}
return nodes;
}
private DynamicNode CreateNode(Category category)
{
// Create a new node for the category
DynamicNode node = new DynamicNode();
node.Name = category.Name;
// ... set node properties here ...
// If the category has children, then continue down the tree
// and create nodes for them. This will continue recursively
// to the bottom of the tree.
// Note that I'm just guessing on the property names because
// you didn't show us the code for what your entity actually
// looks like. This is why you should always show what code
// you've attempted - you can get better, more precise answers
// instead of complete guesses.
if (category.Children != null)
{
foreach (var child in category.Children)
{
// For each child, recursively branch into them.
node.Children.Add(CreateNode(child));
}
}
return Node;
}
Please note that this is no way tested or researched - it's only to show a tree traversal.
I have a complex object. For example a SCHOOL object that contains a collection of PERSON object. How can I use the ObjectDataSource control with a FormView and flatten the complex object? An example display would be to display the school name and comma separate the students on the page. Is this possible?
I.E.
public string Id
{
get { return m_id; }
set { m_id = value; }
}
public string SchoolName
{
get { return m_schoolName; }
set { m_schoolName = value; }
}
public List(Person> Students
{
get { return m_students; }
set { m_cast = students; }
}
Found the solution here:
Displaying an IGrouping<> with nested ListViews.
I nested a DataList control inside my FormView control to get it working.
I have a multiple web sits asp.net application.
In this application different domains using the same pages.
All pages inherit from base class named: PageBase
wich inherit from System.Web.UI.Page.
By using: HttpContext.Current.Request.ServerVariables["HTTP_HOST"]
i cen determine what is the domain and then get all the info i need
for this domain and everything is working good.
My problem begin when i want to use different visitor counter for each site based on session.
Because Global.asax have Global events:
Session_Start
Session_End
simple counter will count all visitors on all sites together.
I try to make code behind for the Global.asax in different class
but i cold not get in that class the PageBase(System.Web.UI.Page) web site info.
I will be very thankful for any ideas to solve this problem
cheinan
I am assuming that you are able to browse from one "site" to the other within the same session and that there is only one session created.
In this case, you need to add the following to your Session:
Session["CountedHosts"] = new List<string>();
Then, on your base page, add the following:
var host = Request.ServerVariables["HTTP_HOST"];
var countedHosts = Session["CountedHosts"] as List<string>;
if (countedHosts != null && !countedHosts.Contains(host))
{
countedHosts.Add(host);
}
Then on session end, record each host that was visited.
var countedHosts = Session["CountedHosts"] as List<string>;
if (countedHosts != null)
{
foreach (var host in countedHosts)
{
//Log it
}
}
I am not able to browse from one "site" to the other within the same session each site have is on
different session created.
but i am very thankful to you because you gave me en idea
how to solv this problem
here is what i did:
i created counter class with Dictionary "onlineList" were i automatic creat for each site a key:
public abstract class counter{
public static Dictionary<string, int> onlineList = new Dictionary<string, int>();
//do add one count
public static void doSiteCountOn(string siteID)
{
if (onlineList.ContainsKey(siteID))
{
onlineList[siteID] += 1;
}
else
{
onlineList.Add(siteID, 1);
}
}
//do less one count
public static void doSiteCountOff(string siteID)
{
if (onlineList.ContainsKey(siteID))
{
onlineList[siteID] -= 1;
}
else
{
onlineList.Add(siteID, 0);
}
}
//get the count
public static string onlineCount(string siteID)
{
if (onlineList.ContainsKey(siteID))
{
return onlineList[siteID].ToString();
}
else
{
return "0";
}
}
//reset the count if needed
public static void resetCount(string siteID)
{
if (onlineList.ContainsKey(siteID))
{
onlineList[siteID] = 0;
}
}}
on my base page i check if there is Session["siteID"]
and if not i start one and make my counter class to add 1 to the site counter:
if (Session["siteID"] == null){
Session["siteID"] = _siteID;
counter.doSiteCountOn(_siteID);}
and finaly on my Session_End i do one count less:
void Session_End(object sender, EventArgs e){
if (Session["siteID"] != null)
{
counter.doSiteCountOff(Session["siteID"].ToString());
}}
thank for your halp
and sorry for my late respons
cheinan