Blazor
To accomplish this task, use the following controller:
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Blazor.SystemModule;
using DevExpress.ExpressApp.SystemModule;
using dxTestSolution.Module.BusinessObjects;
namespace dxTestSolution.Blazor.Server.Controllers;
public class CustomBlazorController2 :ObjectViewController<ListView, MyTask> {
BlazorNewObjectViewController _BlazorNewObjectViewController;
NewItemRowListViewController _NewItemRowListViewController;
protected override void OnActivated() {
base.OnActivated();
_BlazorNewObjectViewController = Frame.GetController<BlazorNewObjectViewController>();
_NewItemRowListViewController = Frame.GetController<NewItemRowListViewController>();
if(_BlazorNewObjectViewController != null) {
_BlazorNewObjectViewController.NewObjectAction.Active["test"] = false;
}
if(_NewItemRowListViewController != null) {
_NewItemRowListViewController.CustomCalculateNewItemRowPosition += Cnt2_CustomCalculateNewItemRowPosition;
}
}
private void Cnt2_CustomCalculateNewItemRowPosition(object sender, CustomCalculateNewItemRowPositionEventArgs e) {
e.NewItemRowPosition = NewItemRowPosition.Top;
}
protected override void OnDeactivated() {
base.OnDeactivated();
if(_BlazorNewObjectViewController != null) {
_BlazorNewObjectViewController.NewObjectAction.Active.RemoveItem("test");
}
if(_NewItemRowListViewController != null) {
_NewItemRowListViewController.CustomCalculateNewItemRowPosition -= Cnt2_CustomCalculateNewItemRowPosition;
}
}
}
ASP.NET WebForms
By default, when the New action is deactivated or disabled, the New Item Row feature is disabled as well. This is logical, because the New Action may be deactivated due to security reasons as well.
To prevent the default behavior or keep the capability to create new records directly in XAF List Editors without the New Action in the main menu, consider one of the two totally different strategies.
1. Deactivating the New Action and overriding the dependent ListEditor behavior.
1.1. Deactivate required Actions in the main menu:
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Web.SystemModule;
using MainDemo.Module.BusinessObjects;
namespace MainDemo.Module.Web.Controllers {
public class MyViewController : ObjectViewController<ListView, Contact> {
private const string UnavailableForContactActiveKey = "UnavailableForContact";
private NewObjectViewController newController = null;
private ListViewController webListViewController = null;
protected override void OnActivated() {
base.OnActivated();
newController = Frame.GetController<NewObjectViewController>();
if(newController != null) {
newController.NewObjectAction.Active.SetItemValue(UnavailableForContactActiveKey, false);
}
webListViewController = Frame.GetController<ListViewController>();
if(webListViewController != null) {
webListViewController.EditAction.Active.SetItemValue(UnavailableForContactActiveKey, false);
}
}
protected override void OnDeactivated() {
base.OnDeactivated();
if(newController != null) {
newController.NewObjectAction.Active.RemoveItem(UnavailableForContactActiveKey);
}
if(webListViewController != null) {
webListViewController.EditAction.Active.RemoveItem(UnavailableForContactActiveKey);
}
}
}
}
Refer to the Task-Based Help > How to: Deactivate (Hide) an Action in Code article for more details.
1.2. Subscribe to the NewItemRowListViewController.CustomCalculateNewItemRowPosition event or override the NewItemRowListViewController.CalculateNewItemRowPosition method to control the New Item Row feature availability manually:
C#using DevExpress.ExpressApp;
using DevExpress.ExpressApp.SystemModule;
namespace MainDemo.Module.Controllers {
public class MyNewItemRowListViewController : NewItemRowListViewController {
protected override NewItemRowPosition CalculateNewItemRowPosition() {
NewItemRowPosition result = NewItemRowPosition.None;
if(View.Model != null && View.AllowEdit && View.AllowNew) {
result = ((IModelListViewNewItemRow)View.Model).NewItemRowPosition;
}
return result;
}
}
}
If you are inheriting from a system Controller, do NOT specify the TargetViewId, TargetObjectType and TargetViewNesting properties, and check the View.Id, View.ObjectType, View.IsRoot and other suitable conditions in the CalculateNewItemRowPosition method. Refer to the Customize Controllers and Actions topic to learn how to handle controllers' events and override their methods.
Since you are ignoring the NewObjectViewController.NewObjectAction.Active/Enabled state completely, you may want to additionally check for security permissions and other things manually (see the UpdateActionState method of the NewObjectViewController class from our sources for more details).
2. Hiding the New Action control in nested views without Action deactivation.
C#using System.ComponentModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.SystemModule;
using DevExpress.ExpressApp.Templates.ActionControls;
namespace MainDemo.Module.Controllers {
public class HideNewActionWithoutDeactivationViewController : ViewController {
private ActionControlsSiteController actionControlsSiteController = null;
private FillActionContainersController fillActionsController = null;
public HideNewActionWithoutDeactivationViewController() {
TargetViewId = "Contact_Tasks_ListView";
}
protected override void OnActivated() {
base.OnActivated();
actionControlsSiteController = Frame.GetController<ActionControlsSiteController>();
if(actionControlsSiteController != null) {
actionControlsSiteController.CustomAddActionControlToContainer += ActionControlsSiteController_CustomAddActionControlToContainer;
}
fillActionsController = Frame.GetController<FillActionContainersController>();
if(fillActionsController != null) {
fillActionsController.CustomRegisterActionInContainer += FillActionsController_CustomRegisterActionInContainer;
}
}
private void DisableActionControlCreation(HandledEventArgs args, string actionId) {
if(actionId == NewObjectViewController.NewActionId) {
args.Handled = true;
}
}
private void FillActionsController_CustomRegisterActionInContainer(object sender, CustomRegisterActionInContainerEventArgs e) {
DisableActionControlCreation(e, e.Action.Id);
}
private void ActionControlsSiteController_CustomAddActionControlToContainer(object sender, CustomAddActionControlEventArgs e) {
DisableActionControlCreation(e, e.Action.Id);
}
protected override void OnDeactivated() {
if(actionControlsSiteController != null) {
actionControlsSiteController.CustomAddActionControlToContainer -= ActionControlsSiteController_CustomAddActionControlToContainer;
}
if(fillActionsController != null) {
fillActionsController.CustomRegisterActionInContainer -= FillActionsController_CustomRegisterActionInContainer;
}
base.OnDeactivated();
}
}
}
Events used in this approach are raised when the current Frame is initialized. If this Frame is a Window, the View that is about to be displayed is unknown. So, this approach cannot be used to hide the New action only in a particular root View. However, the View ID is available in nested Frames at this moment. So, this approach is suitable if you need to hide the New action in a nested ListView shown for an associated collection. For instance, in the code example, customization is applied to the Tasks ListView from the Contact DetailView (Contact_Tasks_ListView).
Finally, there is another, but yet more complicated strategy with deactivating the Action and overriding the ListEditor behavior in a more tricky way, where the custom Active key, e.g., "UnavailableForContact", is excluded from processing, but we would like to refrain from sharing this code due to its size and complexity.
Attached is a sample project for 12.1.7.
Thank you very much Dennis.The code has worked
Hi support, is there an example to manage security permissions when using this mode? above refer to the UpdateActionState method of the NewObjectViewController controller but I did not find the solution.
thanks
giuseppe
In the NewObjectViewController.UpdateActionState method from our sources, you can see how our internal DataManipulationRight.IsAddToCollectionAllowed and DataManipulationRight.CanEdit methods are used to evaluate security permissions. Alternatively, you can use a more documented SecuritySystem.IsGranted method, as shown in the Access the Security System in Code topic.
Running into the same issue with XAF v24.1.5 in Blazor. The controller shown above removes both the 'New' button as well as the in-line '+' button.
I wish there was an option to set a List View to ONLY edit in-line or only edit in a tab. If it's in-line, show the '+' button, if it's tab, show the 'New' button. Also, setting in-line editing would disable opening a tab when clicking on a row.
It's not a good user experience to have a mixture of those two edit behaviors in one list view. I can see scenarios where the tab makes a lot of sense, but for example for the one below, the user only manipulates two fields (Last Updated On and Last Updated By are set by EF automatically) and showing a new tab for that makes no sense.
Hello,
I created a separate ticket on your behalf: T1254296: How to hide the New Action from the main menu, but still have it available inline as the New Item Row feature. We placed it in our processing queue and will process it shortly.
Thanks,
Andrey