Hello,
I'd like to be able to change the caption of a group on the web conditionally based on the current user
For example, I have a filter of projects in a customer object, and I want it to say <UserName>'s Projects in the tab
Is this possible?
We have closed this ticket because another page addresses its subject:
How to change a DetailView editor or ListView column caption dynamicallyHow can I change a layout group caption in a web controller?
Answers
Hello Mike,
Thanks for the update.
Your code should not work because the info you put in the application model is not synchronized with the View. Please refer to the Access the Application Model in Code help topic for more information.
However, the following code works fine for me with the MainDemo.Web application:
C#using System;
using System.Web.UI.WebControls;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Utils;
using DevExpress.ExpressApp.Web.Editors;
using DevExpress.ExpressApp.Web.Layout;
using DevExpress.Web;
using MainDemo.Module.BusinessObjects;
namespace MainDemo.Module.Web.Controllers {
public class ChangeLayoutGroupCaptionViewController : ObjectViewController<DetailView, Contact> {
TabPage tabPageToChange = null;
Label layoutGroupCaptionToChange = null;
protected override void OnActivated() {
base.OnActivated();
((WebLayoutManager)View.LayoutManager).ItemCreated += new EventHandler<ItemCreatedEventArgs>(ChangeLayoutGroupCaptionViewController_ItemCreated);
((WebLayoutManager)View.LayoutManager).PageControlCreated += ChangeLayoutGroupCaptionViewController_PageControlCreated;
View.CurrentObjectChanged += View_CurrentObjectChanged;
}
protected override void OnDeactivated() {
((WebLayoutManager)View.LayoutManager).ItemCreated -= new EventHandler<ItemCreatedEventArgs>(ChangeLayoutGroupCaptionViewController_ItemCreated);
((WebLayoutManager)View.LayoutManager).PageControlCreated -= ChangeLayoutGroupCaptionViewController_PageControlCreated;
View.CurrentObjectChanged -= View_CurrentObjectChanged;
tabPageToChange = null;
layoutGroupCaptionToChange = null;
base.OnDeactivated();
}
private void View_CurrentObjectChanged(object sender, EventArgs e) {
UpdateCaptions();
}
private void UpdateCaptions() {
if(ViewCurrentObject != null) {
if(tabPageToChange != null) {
tabPageToChange.Text = "My Phone Numbers " + ViewCurrentObject.FullName;
}
if(layoutGroupCaptionToChange != null) {
layoutGroupCaptionToChange.Text = "My Contact " + ViewCurrentObject.FullName;
}
}
}
private void ChangeLayoutGroupCaptionViewController_PageControlCreated(object sender, PageControlCreatedEventArgs e) {
ASPxPageControl tabControl = e.PageControl;
if(tabControl != null) {
tabControl.Init += (s1, e1) => {
tabPageToChange = tabControl.TabPages.FindByText("Phone Numbers");
UpdateCaptions();
};
}
}
void ChangeLayoutGroupCaptionViewController_ItemCreated(object sender, ItemCreatedEventArgs e) {
if(e.ModelLayoutElement.Id == "Contact") {
e.TemplateContainer.Init += (s, args) => {
if(e.TemplateContainer.CaptionControl != null) {
layoutGroupCaptionToChange = e.TemplateContainer.CaptionControl as Label;
UpdateCaptions();
}
};
}
}
}
}
Visual BasicImports System
Imports System.Web.UI.WebControls
Imports DevExpress.ExpressApp
Imports DevExpress.ExpressApp.Utils
Imports DevExpress.ExpressApp.Web.Editors
Imports DevExpress.ExpressApp.Web.Layout
Imports DevExpress.Web
Imports MainDemo.Module.BusinessObjects
Namespace MainDemo.Module.Web.Controllers
Public Class ChangeLayoutGroupCaptionViewController
Inherits ObjectViewController(Of DetailView, Contact)
Private tabPageToChange As TabPage = Nothing
Private layoutGroupCaptionToChange As Label = Nothing
Protected Overrides Sub OnActivated()
MyBase.OnActivated()
AddHandler CType(View.LayoutManager, WebLayoutManager).ItemCreated, AddressOf ChangeLayoutGroupCaptionViewController_ItemCreated
AddHandler CType(View.LayoutManager, WebLayoutManager).PageControlCreated, AddressOf ChangeLayoutGroupCaptionViewController_PageControlCreated
AddHandler View.CurrentObjectChanged, AddressOf View_CurrentObjectChanged
End Sub
Protected Overrides Sub OnDeactivated()
RemoveHandler CType(View.LayoutManager, WebLayoutManager).ItemCreated, AddressOf ChangeLayoutGroupCaptionViewController_ItemCreated
RemoveHandler CType(View.LayoutManager, WebLayoutManager).PageControlCreated, AddressOf ChangeLayoutGroupCaptionViewController_PageControlCreated
RemoveHandler View.CurrentObjectChanged, AddressOf View_CurrentObjectChanged
tabPageToChange = Nothing
layoutGroupCaptionToChange = Nothing
MyBase.OnDeactivated()
End Sub
Private Sub View_CurrentObjectChanged(ByVal sender As Object, ByVal e As EventArgs)
UpdateCaptions()
End Sub
Private Sub UpdateCaptions()
If ViewCurrentObject IsNot Nothing Then
If tabPageToChange IsNot Nothing Then
tabPageToChange.Text = "My Phone Numbers " & ViewCurrentObject.FullName
End If
If layoutGroupCaptionToChange IsNot Nothing Then
layoutGroupCaptionToChange.Text = "My Contact " & ViewCurrentObject.FullName
End If
End If
End Sub
Private Sub ChangeLayoutGroupCaptionViewController_PageControlCreated(ByVal sender As Object, ByVal e As PageControlCreatedEventArgs)
Dim tabControl As ASPxPageControl = e.PageControl
If tabControl IsNot Nothing Then
AddHandler tabControl.Init, Sub(s1, e1)
tabPageToChange = tabControl.TabPages.FindByText("Phone Numbers")
UpdateCaptions()
End Sub
End If
End Sub
Private Sub ChangeLayoutGroupCaptionViewController_ItemCreated(ByVal sender As Object, ByVal e As ItemCreatedEventArgs)
If e.ModelLayoutElement.Id = "Contact" Then
AddHandler e.TemplateContainer.Init, Sub(s, args)
If e.TemplateContainer.CaptionControl IsNot Nothing Then
layoutGroupCaptionToChange = TryCast(e.TemplateContainer.CaptionControl, Label)
UpdateCaptions()
End If
End Sub
End If
End Sub
End Class
End Namespace
Take special note here I access the underlying Label and ASPxPageControls and customize them directly. Let me know if this helps.
See Also: How to change a DetailView editor or ListView column caption dynamically
Thanks,
Dennis
Is this example already valid?
I set as Text a property of the current ViewCurrentObject but if I nagivate back and forward using the arrows at the top of detailview the ViewCurrentObject I always populated with the previous object.
C#using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AppPPM.Module.BusinessObjects.GIS;
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Actions;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp.Layout;
using DevExpress.ExpressApp.Model.NodeGenerators;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Templates;
using DevExpress.ExpressApp.Utils;
using DevExpress.ExpressApp.Web;
using DevExpress.ExpressApp.Web.Layout;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.Validation;
using DevExpress.Web;
namespace AppPPM.Module.Web.Controllers
{
// For more typical usage scenarios, be sure to check out https://documentation.devexpress.com/eXpressAppFramework/clsDevExpressExpressAppViewControllertopic.aspx.
public partial class ChangeKpiTabCaptionViewController : ObjectViewController<DetailView,PPM_ProjectPortfolio>
{
public ChangeKpiTabCaptionViewController()
{
InitializeComponent();
// Target required Views (via the TargetXXX properties) and create their Actions.
}
void ChangeLayoutGroupCaptionViewController_ItemCreated(object sender, ItemCreatedEventArgs e)
{
TabbedGroupTemplateContainer tabbedGroup = e.TemplateContainer as TabbedGroupTemplateContainer;
if (tabbedGroup != null)
{
tabbedGroup.Load += (s, args) =>
{
ASPxPageControl tabControl = tabbedGroup.Controls[0].Controls[0] as ASPxPageControl;
if (tabControl != null)
{
TabPage tab = tabControl.TabPages.FindByText("Status");
if (tab != null)
{
//((WebLayoutManager)View.LayoutManager).ItemCreated -= new EventHandler<ItemCreatedEventArgs>(ChangeLayoutGroupCaptionViewController_ItemCreated);
if (ViewCurrentObject != null && ViewCurrentObject.vCurrentKPI != null && ViewCurrentObject.vCurrentKPI.KpiCampaignID != null && ViewCurrentObject.vCurrentKPI.KpiCampaignID.EndDate != null)
{
tab.Text = string.Format("Status {0:MM.yyyy}", ViewCurrentObject.vCurrentKPI.KpiCampaignID.EndDate);
} else
{
tab.Text = "Status";
}
}
}
};
}
}
protected override void OnActivated()
{
base.OnActivated();
((WebLayoutManager)View.LayoutManager).ItemCreated += new EventHandler<ItemCreatedEventArgs>(ChangeLayoutGroupCaptionViewController_ItemCreated);
// Perform various tasks depending on the target View.
}
protected override void OnDeactivated()
{
((WebLayoutManager)View.LayoutManager).ItemCreated -= new EventHandler<ItemCreatedEventArgs>(ChangeLayoutGroupCaptionViewController_ItemCreated);
base.OnDeactivated();
}
}
}
thanks
Giuseppe
@Giuseppe: Please check out my updated code above. I additionally handled the View.CurrentObjectChanged event as described at Q563644.
Hello Mike,
I suggest you handle the ItemCreated event of the WebLayoutManager class. Event arguments of this event provide the necessary information including the info from the model, DetailViewItem and a template used for this item. So, I believe that you can access the required control and change the caption as required based on the SecuritySystem.CurrentUserName property.
This functionality is not described in our documentation, since it's internal, but you can learn more on how this works, from our sources. For example, check the …\DevExpress.ExpressApp.Modules\DevExpress.ExpressApp.ConditionalEditorState.Web\EditorStateCustomizationDetailViewController.cs file for some example code.
Let me know if you need additional clarification.
Thanks,
Dennis
Hi Dennis,
This seems to be working just fine, but when I change the caption the site does not reflect the change until I refresh the page
Here is my code:
[code]
Private Sub WebLayoutManager_ItemCreated(ByVal sender As Object, ByVal e As DevExpress.ExpressApp.Web.Layout.ItemCreatedEventArgs)
Dim gpcGroupControl As DevExpress.ExpressApp.Web.Layout.LayoutGroupTemplateContainer
Dim tpcTabbedContainer As DevExpress.ExpressApp.Web.Layout.TabbedGroupTemplateContainer
Dim oViewCaptionLocaleSetting As ViewCaptionLocaleSetting
Dim oUser As User = DevExpress.ExpressApp.SecuritySystem.CurrentUser
If TypeOf e.TemplateContainer Is DevExpress.ExpressApp.Web.Layout.LayoutGroupTemplateContainer Then
If gpcGroupControl.Caption = "Projects" Then
If gpcGroupControl.Info.Attributes.ContainsKey("Caption") = False Then
gpcGroupControl.Info.AddAttribute("Caption", oUser.Name + "'s Projects")
Else
gpcGroupControl.Info.Attributes("Caption").Value = oUser.Name + "'s Projects"
End If
End If
End If
End Sub
Private Sub ViewCaptionLocaleController_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
Dim vwdDetailView As DetailView
Dim wlmLayoutManager As DevExpress.ExpressApp.Web.Layout.WebLayoutManager
If TypeOf View Is DetailView Then
vwdDetailView = View
wlmLayoutManager = vwdDetailView.LayoutManager
RemoveHandler wlmLayoutManager.ItemCreated, AddressOf WebLayoutManager_ItemCreated
AddHandler wlmLayoutManager.ItemCreated, AddressOf WebLayoutManager_ItemCreated
End If
End Sub
[/code]
Is there another approach I should use here?