liferay messageboard link to first/last message in thread - liferay

i need to add a link to the first/last post/message to each message. at the moment there is a "Top" link that jumps to begin of page. i want it to jump to first post and an additional link "bottom" that jumps to last post of thread.
Adding the links is not the problem but is there a easy way to get the last message of a thread?

i got it:
because i need also a link to first message i created a more general private method that is called by 2 public methods (getLastMessageOfThread and ...):
private Long getMessageOfThread(long threadId, boolean last) {
Long result = null;
try {
List<MBMessage> threadMessages = MBMessageLocalServiceUtil.getThreadMessages(threadId, 0, messageCreateDateComp);
if (Validator.isNotNull(threadMessages)) {
result = last ? threadMessages.get(threadMessages.size() - 1).getMessageId() : threadMessages.get(0).getMessageId();
}
} catch (SystemException e) {
throw new IllegalStateException("Problem on getting thread messages for thread id " + threadId + ", cause:", e);
}
return result;
}
Then i hooked view_thread_message.jsp:
...
<ul class="edit-controls lfr-component">
<%
String firstMessageId = String.valueOf(MyMessageboardLocalServiceUtil.getFirstMessageOfThread(thread.getThreadId()));
String lastMessageId = String.valueOf(MyMessageboardLocalServiceUtil.getLastMessageOfThread(thread.getThreadId()));
String firstMessageAnchor ="#" + renderResponse.getNamespace() + "message_" + firstMessageId;
String lastMessageAnchor ="#" + renderResponse.getNamespace() + "message_" + lastMessageId;
%>
<liferay-portlet:renderURL varImpl="lastMessageUrl">
<portlet:param name="struts_action" value="/message_boards/view_message" />
<portlet:param name="messageId" value="<%= lastMessageId %>" />
</liferay-portlet:renderURL>
<liferay-portlet:renderURL varImpl="firstMessageUrl">
<portlet:param name="struts_action" value="/message_boards/view_message" />
<portlet:param name="messageId" value="<%= firstMessageId %>" />
</liferay-portlet:renderURL>
<li>
<liferay-ui:icon
image="top"
label="<%= true %>"
url="<%= firstMessageUrl.toString() + firstMessageAnchor %>"
/>
</li>
<li>
<liferay-ui:icon
image="bottom"
label="<%= true %>"
url="<%= lastMessageUrl.toString() + lastMessageAnchor %>"
/>
</li>
...
probably it could be don easier but i'am an absolute liferay noob. and for the sake of completeness here the used comparator:
private static class MBMessageDateComparator implements Comparator<MBMessage> {
#Override
public int compare(MBMessage arg0, MBMessage arg1) {
Long time0 = arg0.getCreateDate().getTime();
Long time1 = arg0.getCreateDate().getTime();
return time0.compareTo(time1);
}
}
Assuming that the first message has the smallest time stamp (seems to be a correct assumption).

Related

search mvc staying same page

I'm using MVC5 and I want to search for a result and stay at the same page, here is my method in my controller (LiaisonsProjetsPPController) that do the operation of searching :
public ActionResult IndexAjoutML(int id, string SearchString)
{
PartiesPrenantesEntities db = new PartiesPrenantesEntities();
ViewBag.idProjet = id;
ViewBag.searchString = SearchString;
IQueryable<ActivitesPP> qry = this.db.ActivitesPP.Intersect(from item in this.db.LiaisonsProjetsPP where item.idProjet == id select item.ActivitesPP).Include(model => model.Activites.CatActivites);
var act = from s in db.CatActivites
select s;
if (!String.IsNullOrEmpty(SearchString))
return PartialView("~/Views/ActivitesPP/IndexAjoutProjet.cshtml", this.db.ActivitesPP.Where(s => s.PartiesPrenantes.nomPP.Contains(SearchString)).Except(qry));
else
return PartialView("~/Views/ActivitesPP/IndexAjoutProjet.cshtml", this.db.ActivitesPP.Except(qry));
}
Then in my view (Views/ActivitesPP/IndexAjoutProjet) I have my search form and the div of the display result :
#using (Ajax.BeginForm("IndexAjoutML", "LiaisonsProjetsPP", FormMethod.Post,
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "search-results"
}, new { #id = "searchFormPP" }))
{
<p>
<label>Partie prenante: </label> #Html.TextBox("SearchString")
<input id="inputRecherche" name="SearchString" type="submit" value="Rechercher" />
</p>
}
<div id="search-results">
#{foreach (var catactivite in Model.GroupBy(model => model.Activites.CatActivites))
{
String couleurCategorie = catactivite.Key.couleurCategorie;
String couleurTexte = CustomHelpers.GetForegroundColor(couleurCategorie);
//Image de la partie prenante
<div class="panel-heading unhide" style="background-image: none; color: #couleurTexte; background-color: #couleurCategorie; padding: 2px;">
</div>
foreach (var pp in catactivite)
{
String nomPP = (pp.idPP == null ? "Inconnu" : pp.PartiesPrenantes.nomPP);
String dateAffichee;
String imgPP = "../../Images/Profils/" + (pp.PartiesPrenantes.imgPP ?? "avatar.png");
if (pp.finActivite == null)
{
dateAffichee = "Depuis le " + String.Format("{0:d/MM/yyyy}", pp.debutActivite);
}
else
{
dateAffichee = "Depuis le " + String.Format("{0:d/MM/yyyy}", pp.debutActivite) + ", jusqu'au " + String.Format("{0:d/MM/yyyy}", pp.finActivite);
}
<div class="panel panel-primary">
<div class="panel-heading unhide" style="color: #couleurTexte; background-color: #couleurCategorie;">
<div style="float: left">
<img class="imgPP img-circle" src="#(imgPP)" />
</div>
<h5>#pp.Activites.libelleActivite (#Html.Raw(pp.idLieu == 999 ? "National" : pp.Lieux.nomLieu))</h5>
<h6>#pp.PartiesPrenantes.nomPP</h6>
</div>
<div class="panel-body hiddenPart">
#if (pp.idPP != null)
{
<label>Commentaire</label>
<p>#(pp.commentaireActivite ?? "Pas plus de détails..")</p>
#Html.Action("CreateForm", "LiaisonsProjetsPP", new { idActivite = pp.idActivite, idProjet = ViewBag.idProjet })
}
</div>
</div>
}
}
}
</div>
}
else
{
#Html.Raw("<p>Aucune partie prenante disponible..")
#Html.Raw("(attention: pour être ajoutée, une partie prenante doit posséder au moins une activité référencée..)</p>")
}
In my view i call my method of search (Views/Projets/Details): #{ Html.RenderAction("IndexAjoutML", "LiaisonsProjetsPP", new { idProjet = Model.idProjet, searchString = Model.searchString }); }
The search work but it redirects me to another page http://localhost:49612/LiaisonsProjetsPP/IndexAjout/1 instead of staying at this page http://localhost:49612/Projets/Details/1.
What you are trying to do seems to be loading results unobtrusively with an AJAX form. The Professional ASP.NET MVC 5 book by John Galloway et al. has a nice section on this, but realizing that no one reads books I will provide a link to a site with a code sample for it.
The .NET Funda site describes here exactly how to search and return the results to the same page without a complete refresh using unobtrusive-ajax.
Likely what you are missing is a reference to jquery.unobtrusive-ajax.min.js. Other posts on Stack Overflow also reference this topic, but I realize you might not know the correct search terms. Try looking further into "AJAX partial view unobtrusive loading" as search terms for further research.
This example is from the book I mentioned from John Galloway.
A JavaScript error message.
function searchFailed(){
$("#searchresults").html("Sorry, there was a problem searching.");
}
This is what a simple Ajax form should look like. Note the "GET" form method.
<div class="panel panel-default">
<div class="panel-heading">
Artist Search
</div>
<div class="panel-body">
#using(Ajax.BeginForm("ArtistSearch", "Home",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET",
OnFailure = "searchFailed",
LoadingElementID = "ajax-loader",
UpdateTargetId = "searchresults",
}))
{
<input type="text" name="q" />
<input type="submit" value="search" />
<img id="ajax-loader"
src="#Url.Content("~/Images/ajax-loader.gif")"
style="display:none" />
}
<div id="searchresults"></div>
</div>
</div>
This is the method responsible for returning the partial view:
public ActionResult ArtistSearch(string q)
{
var artists = GetArtists(q);
return PartialView(artists);
}
This is a search method.
public List<Artist> GetArtists(string searchString)
{
return storeDB.Artist.Where(a => a.Name.Contains(searchString)).ToList();
}
Note that the method for returning the partial view is simply "return PartialView(model);"

Telerik grid updates not working in batch editing

I'm using RadGrid in ASPX, .net 4.5. The data comes up and displays in my grid fine, but I cannot update, insert, or delete records. I have followed the sample version as closely as I can:
http://demos.telerik.com/aspnet-ajax/grid/examples/data-editing/batch-editing/defaultcs.aspx
When I try to modify data in the grid, then hit Save, the grid reloads and the data is unchanged. No errors, just no updates.
Originally I had the grid wrapped in ajax panel, but when these problems occurred, I removed it. That made not much difference; though when I was using ajax panel, often times clicking the Save icon did absolutely nothing. Or appeared to do nothing. So with that gone, the page/grid does normal postbacks EXCEPT that none of my event handlers are being called. Page_Load gets called, but nothing else (for example RadGrid1_BatchEditCommand, RadGrid1_ItemUpdated). It seems these should be getting called.
ASPX code:
<telerik:RadScriptManager runat="server" ID="RadScriptManager1" />
<telerik:RadListBox runat="server" ID="SavedChangesList" Width="600px" Height="200px" Visible="false"></telerik:RadListBox>
<telerik:RadGrid ID="RadGrid1" GridLines="None" runat="server" AllowAutomaticDeletes="True"
AllowAutomaticInserts="True" PageSize="10" Skin="Default" OnItemDeleted="RadGrid1_ItemDeleted" OnItemInserted="RadGrid1_ItemInserted"
OnItemUpdated="RadGrid1_ItemUpdated" OnPreRender="RadGrid1_PreRender" AllowAutomaticUpdates="True" AllowPaging="True"
AutoGenerateColumns="False" Width="1000px" OnBatchEditCommand="RadGrid1_BatchEditCommand" DataSourceID="sqlContractMatrix">
<MasterTableView CommandItemDisplay="TopAndBottom" DataKeyNames="ID" DataSourceID="sqlContractMatrix" HorizontalAlign="NotSet" EditMode="Batch" AutoGenerateColumns="False">
<BatchEditingSettings EditType="Cell" />
<SortExpressions>
<telerik:GridSortExpression FieldName="SiteID,ProductID" SortOrder="Descending" />
</SortExpressions>
<Columns>
<telerik:GridTemplateColumn HeaderText="Site" HeaderStyle-Width="150px" UniqueName="SiteID" DataField="SiteID">
<ItemTemplate>
<%# Eval("SiteName") %>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadDropDownList runat="server" ID="ddlSites" AppendDataBoundItems="true" DataValueField="SiteID" DataTextField="SiteName" DataSourceID="sqlSites">
</telerik:RadDropDownList>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="Product" HeaderStyle-Width="150px" UniqueName="ProductID" DataField="ProductID">
<ItemTemplate>
<%# Eval("ProductName") %>
</ItemTemplate>
<EditItemTemplate>
<telerik:RadDropDownList runat="server" ID="ddlProducts" DropDownWidth="250" DropDownHeight="400" DefaultMessage="Product" AppendDataBoundItems="true" DataValueField="ProductID" DataTextField="ProductName" DataSourceID="sqlProducts">
</telerik:RadDropDownList>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridAttachmentColumn DataSourceID="sqlContractMatrix" MaxFileSize="1048576" HeaderStyle-Width="250px"
EditFormHeaderTextFormat="Upload File:" HeaderText="HTML Template" AttachmentDataField="BinaryData"
AttachmentKeyFields="ID" FileNameTextField="TemplateFileBinary" DataTextField="TemplateFileBinary"
UniqueName="TemplateFileBinary">
</telerik:GridAttachmentColumn>
<%--
<telerik:GridBoundColumn DataField="TemplateFile" HeaderStyle-Width="200px" HeaderText="Template"
SortExpression="TemplateFile" UniqueName="TemplateFile">
</telerik:GridBoundColumn>
--%>
<telerik:GridBoundColumn DataField="PDFName" HeaderStyle-Width="200px" HeaderText="PDF Name"
SortExpression="PDFName" UniqueName="PDFName">
</telerik:GridBoundColumn>
<telerik:GridButtonColumn ConfirmText="Delete this record?" ConfirmDialogType="RadWindow"
ConfirmTitle="Delete" HeaderText="Delete" HeaderStyle-Width="50px" ButtonType="ImageButton"
CommandName="Delete" Text="Delete" UniqueName="DeleteColumn">
</telerik:GridButtonColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
<asp:SqlDataSource ID="sqlContractMatrix" runat="server" ConnectionString="<%$ ConnectionStrings:FitTrack %>"
DeleteCommand="DELETE FROM ContractMatrix WHERE ID = #ID"
InsertCommand="INSERT INTO ContractMatrix (SiteID, ProductID, TemplateFile, PDFName, LastModifiedDate, LastModifiedByID) VALUES (#SiteID, #ProductID, #TemplateFile, #PDFName, #LastModifiedDate, #LastModifiedByID)"
UpdateCommand="UPDATE ContractMatrix SET SiteID = #SiteID, ProductID = #ProductID, TemplateFile = #TemplateFile, PDFName = #PDFName, LastModifiedDate = GETDATE(), LastModifiedByID = #LastModifiedByID WHERE ID = #ID">
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="SiteID" Type="Int32"></asp:Parameter>
<asp:Parameter Name="ProductID" Type="Int32"></asp:Parameter>
<asp:Parameter Name="TemplateFile" Type="String"></asp:Parameter>
<asp:Parameter Name="PDFName" Type="String"></asp:Parameter>
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="SiteID" Type="Int32"></asp:Parameter>
<asp:Parameter Name="ProductID" Type="Int32"></asp:Parameter>
<asp:Parameter Name="TemplateFile" Type="String"></asp:Parameter>
<asp:Parameter Name="PDFName" Type="String"></asp:Parameter>
<asp:Parameter Name="ID" Type="Int32"></asp:Parameter>
</UpdateParameters>
</asp:SqlDataSource>
<!-- SQL data sources for various lookup tables -->
<asp:SqlDataSource ID="sqlSites" runat="server" ConnectionString="<%$ ConnectionStrings:FitTrack %>" ProviderName="System.Data.SqlClient" SelectCommand="SELECT SiteID, SiteName FROM gym.Site ORDER BY SiteID"></asp:SqlDataSource>
<asp:SqlDataSource ID="sqlProducts" runat="server" ConnectionString="<%$ ConnectionStrings:FitTrack %>" ProviderName="System.Data.SqlClient"></asp:SqlDataSource>
C# code:
protected void RadGrid1_BatchEditCommand(object sender, Telerik.Web.UI.GridBatchEditingEventArgs e)
{
SavedChangesList.Visible = true;
}
protected void RadGrid1_ItemUpdated(object source, Telerik.Web.UI.GridUpdatedEventArgs e)
{
GridEditableItem item = (GridEditableItem)e.Item;
string id = item.GetDataKeyValue("ID").ToString();
if (e.Exception != null)
{
e.KeepInEditMode = true;
e.ExceptionHandled = true;
NotifyUser("Record with ID " + id + " cannot be updated. Reason: " + e.Exception.Message);
}
else
{
NotifyUser("Record with ID " + id + " is updated!");
}
}
protected void RadGrid1_ItemInserted(object source, GridInsertedEventArgs e)
{
if (e.Exception != null)
{
e.ExceptionHandled = true;
NotifyUser("Product cannot be inserted. Reason: " + e.Exception.Message);
}
else
{
NotifyUser("New product is inserted!");
}
}
protected void RadGrid1_ItemDeleted(object source, GridDeletedEventArgs e)
{
GridDataItem dataItem = (GridDataItem)e.Item;
string id = dataItem.GetDataKeyValue("ID").ToString();
if (e.Exception != null)
{
e.ExceptionHandled = true;
NotifyUser("Product with ID " + id + " cannot be deleted. Reason: " + e.Exception.Message);
}
else
{
NotifyUser("Product with ID " + id + " is deleted!");
}
}
Please help. Why are the data updates not occurring? Why are none of the telerik events/methods in the codebehind being called? Only Page_Load() is executing, none of the others.
For me this was down to trying to use OnItemUpdated instead of OnUpdateCommand.
The ItemDeleted, ItemUpdated and ItemInserted events of RadGrid only work in combination with a directly bound ADO type DataSource. I'm using my own DAL so these 3 events weren't firing.
So the fix was to hook up the events OnUpdateCommand and OnDeleteCommand instead. The event handler looks something like this.
protected void radGrid_UpdateCommand(object sender, GridCommandEventArgs e)
{
var gridDataItem = ((GridDataItem)e.Item);
var table = gridDataItem.OwnerTableView;
var keyValues = table.DataKeyValues[gridDataItem.ItemIndex];
// Get key value.
var id = keyValues["id"];
// Get other values
var foo = ((TextBox)gridDataItem["foo"].Controls[0]).Text;
var bar = ((TextBox)gridDataItem["bar"].Controls[0]).Text;
myDAL.Update(id, foo, bar);
}

liferay-ui: discussion tag in custom portlet

I am trying to to imped inside jsp page custom portlet
to allow comments on journal article displayed
to embed .
The problem is it throws g.ClassNotFoundException: org.apache.jsp.view_jsp as following
An error occurred at line: 119 in the jsp file: /discussion.jsp
The method setClassName(String) in the type DiscussionTag is not applicable for the arguments (Class<capture#2-of ? extends JournalArticle>)
116: id="journalCommentsPanel" persistState="<%= true %>"
117: title='<%= LanguageUtil.get(pageContext, "Comments") %>'>
118:
119: <liferay-ui:discussion
120: className="<%= journal.getClass() %>"
121: classPK="31575"
122: formAction="www.google.com"
15:57:13,540 ERROR [PortletRequestDispatcherImpl:108]
org.apache.jasper.JasperException: java.lang.ClassNotFoundException:
org.apache.jsp.discussion_jsp
org.apache.jasper.JasperException: java.lang.ClassNotFoundException:
org.apache.jsp.discussion_jsp
This is my discussion.jsp page
<%
WindowState windowState = null;
PortletMode portletMode = null;
PortletURL currentURLObj = null;
if (renderRequest != null) {
windowState = renderRequest.getWindowState();
portletMode = renderRequest.getPortletMode();
currentURLObj = PortletURLUtil.getCurrent(renderRequest,
renderResponse);
} else if (resourceRequest != null) {
windowState = resourceRequest.getWindowState();
portletMode = resourceRequest.getPortletMode();
currentURLObj = PortletURLUtil.getCurrent(resourceRequest,
resourceResponse);
}
String currentURL = currentURLObj.toString();
ThemeDisplay themeDisplayObject = (ThemeDisplay) request
.getAttribute(WebKeys.THEME_DISPLAY);
//long groupId = ParamUtil.getLong(request, "groupId", scopeGroupId);
long groupId = themeDisplayObject.getScopeGroupId();
String url = PortalUtil.getCurrentURL(request);
String[] urlString = url.split("/");
String urlTitle = urlString[urlString.length - 1];
urlTitle = HttpUtil.decodeURL(urlTitle).trim();
JournalArticle journal = JournalArticleLocalServiceUtil
.getArticleByUrlTitle(groupId, urlTitle);
%>
<portlet:actionURL var="discussionUrl">
<!-- <portlet:param name="jspPage" value="/discussion.jsp" /> -->
</portlet:actionURL>
<portlet:actionURL var="editGreetingURL">
<portlet:param name="jspPage" value="/view.jsp" />
</portlet:actionURL>
<liferay-ui:panel-container extended="<%= false %>"
id="journalCommentsPanelContainer" persistState="<%= true %>">
<liferay-ui:panel collapsible="<%= true %>" extended="<%= true %>"
id="journalCommentsPanel" persistState="<%= true %>"
title='<%= LanguageUtil.get(pageContext, "Comments") %>'>
<portlet:actionURL name="invokeTaglibDiscussion" var="discussionURL" />
<liferay-ui:discussion
className="<%= JournalArticle.class.getName() %>"
classPK="<%= journal.getArticleId() %>"
formAction="www.google.com"
subject="Wall Comments"
userId="<%= journal.getUserId() %>" />
</liferay-ui:panel>
</liferay-ui:panel-container>
and this is my processAction method :
PortletConfig portletConfig = getPortletConfig();
// System.out.println(">>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> inside invoke");
PortalClassInvoker .invoke(true, "com.liferay.portlet.messageboards.action.EditDiscussionAction",
"processAction", new String[] {
"org.apache.struts.action.ActionMapping",
"org.apache.struts.action.ActionForm",
PortletConfig.class.getName(),
ActionRequest.class.getName(),
ActionResponse.class.getName()
}, null, null, portletConfig, actionRequest, actionResponse);
Your error shows this code at line-120 className="<%= journal.getClass() %>" but your discussion.jsp shows className="<%= JournalArticle.class.getName() %>" which is the corrected version I suppose.
I think the portlet is not deployed properly, try re-deploying the portlet or if that does not help try the usual:
undeploy the portlet
and then redeploy
if that does not work:
undeploy
stop server
clear temp directory
clear work directory
start server
deploy the portlet
my one is working properly
my table, WallEntry. Where userid is the id of the user.
List<WallEntry> wallEntry= WallEntryLocalServiceUtil.findByUserId(userId);
for (int i=0;i<wallEntry.size();i++)
{
WallEntry wallobj=wallEntry.get(i);
long id=wallobj.getWallEntryId();
}
portlet action url
<portlet:actionURL name="discussionURL" var="discussionURL">
<portlet:param name="myaction" value="addComments" />
</portlet:actionURL>
liferay-ui:discussion tag
<liferay-ui:discussion
redirect="<%= themeDisplay.getURLCurrent() %>"
classPK="<%= wallEntry.getWallEntryId() %>"
userId="<%= user.getUserId() %>"
className="<%= WallEntry.class.getName() %>"
subject=""
formAction="<%= discussionURL %>"
formName='<%= "fm"+wallEntry.getWallEntryId() %>'
/>
action class
public void discussionURL(ActionRequest request,ActionResponse response)
throws Exception
{
System.out.println("Inside addDiscussion function: "+request.getParameter("myaction"));
}
may be it is helpful for someone.

No such property: exampleInstance for class: test3.ExampleController

Domain
class Example {
String title
Date releaseDate
String author
Boolean paperback
static constraints = {
}
}
Controller
class ExampleController {
def scaffold = true
def search = {
exampleInstance = Example.findAllByTitleIlike("${params.q}%",[max:10, offset:0, sort:"title", order:"asc"])
redirect(action: "list",params)
return
}
def list = {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[exampleInstanceList: Example.list(params),
exampleInstanceTotal: Example.count()]
}
}
View
<div id="search">
<g:form url='[controller: "example", action: "search"]' id="search" name="search" method="get">
<g:textField name="q" value="${params.q}" />
<input type="submit" value="Find" />
</g:form>
</div>
Please Help me is how
Error URI /test3/example/search Class groovy.lang.MissingPropertyException
Message No such property: exampleInstance for class: test3.ExampleController
Use render instead of redirect and pass all the model that are required for the list page.
def search = {
def exampleInstance= Example.findAllByTitleIlike("${params.q}%",[max:10, offset:0, sort:"title", order:"asc"])
render( view:list, model:[ exampleInstance:exampleInstance, params:params ] )

C# How to set a NewLine in Label.text for a CartItem[]?

How to set a NewLine in Label.text for a CartItem[]? Environment.NewLine or \r\n does not work.
CartItem[] items = Profile.Cart.GetItems();
foreach (CartItem i in items)
Label4.Text += i.curDvd.Title + ",$" + i.curDvd.UnitPrice + "*" + i.Quantity + System.Environment.NewLine+"\r\n";
It can display everything in 1 line, but tried \r\n and Enviroment.NewLine, nothing changed.
Why?
Have you tried using more than one "\n" ?
In a web application you should use <br/> if you want new line. Unfortunately you cannot use a label in this case as it will automatically HTML encode the text. You could use a repeater at the place of this label:
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<%# Eval("Title") %>, $<%# Eval("Price") %>
<br/>
</ItemTemplate>
</asp:Repeater>
and in your code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
CartItem[] items = Profile.Cart.GetItems();
rep.DataSource = items.Select(x => new
{
Title = x.curDvd.Title,
Price = x.curDvd.UnitPrice * x.Quantity
});
rep.DataBind();
}
}
Another possible template is to use divs:
<asp:Repeater ID="rep" runat="server">
<ItemTemplate>
<div><%# Eval("Title") %>, $<%# Eval("Price") %></div>
</ItemTemplate>
</asp:Repeater>

Resources