Reputation: 23
When trying to add record in child view, it require to save the parent record. how can i stop this behavior?
Upvotes: 2
Views: 325
Reputation: 2611
I was encountering the same issue, and my workaround was to create a popup window, and use the accept action to trigger a post-save workflow. I created an abstract class to replace the new and current object actions. I also created a few subclasses so that I could trigger the popup when a row in the list view is selected.
public abstract partial class QpPopupActionController<T> : ViewController where T : BaseObject
{
protected NewObjectViewController newObjectViewController;
protected QpPopupWindowShowAction popupWindowAction;
private ListViewProcessCurrentObjectController currentObjectController;
private WindowController windowController;
protected IObjectSpace popupObjectSpace;
private DetailView detailView;
private IRuleSet ruleSet;
// Use CodeRush to create Controllers and Actions with a few keystrokes.
// https://docs.devexpress.com/CodeRushForRoslyn/403133/
protected QpPopupActionController()
{
InitializeComponent();
TargetObjectType = typeof(T);
popupWindowAction = new QpPopupWindowShowAction(this, "Popup" + TargetObjectType.Name + "Action", PredefinedCategory.ObjectsCreation)
{
Caption = "Add Item",
ImageName = "Action_New",
SelectionDependencyType = SelectionDependencyType.Independent,
TargetViewType = ViewType.ListView
};
}
private void CustomizeWindowPopup(object sender, CustomizePopupWindowParamsEventArgs e)
{
// create a new order and assign the selected customer to it.
IsAdding = TypedObject == null;
if (IsAdding)
{
popupObjectSpace = ObjectSpace;
TypedObject = popupObjectSpace.CreateObject<T>();
InitializeNewObject(TypedObject);
}
else
{
popupObjectSpace = Application.CreateObjectSpace<Order>();
TypedObject = popupObjectSpace.GetObject(TypedObject);
}
e.View = Application.CreateDetailView(popupObjectSpace, TypedObject, View);
DialogController = e.DialogController;
DialogController.SaveOnAccept = !IsAdding;
e.DialogController.AcceptAction.Executing += AcceptAction_Executing;
e.DialogController.AcceptAction.ExecuteCompleted += AcceptAction_ExecuteCompleted;
e.DialogController.CancelAction.ExecuteCompleted += CancelAction_ExecuteCompleted;
}
protected abstract void InitializeNewObject(T typedObject);
private void AcceptAction_Executing(object sender, System.ComponentModel.CancelEventArgs e)
{
ruleSet = Validator.GetService(Application.ServiceProvider);
ruleSet.Validate(popupObjectSpace, TypedObject, DefaultContexts.Save);
}
public bool IsAdding { get; set; }
protected override void OnActivated()
{
base.OnActivated();
if (View is ListView)
{
if (View.AllowNew)
{
windowController = Frame.GetController<WindowController>();
newObjectViewController = Frame.GetController<NewObjectViewController>();
if (newObjectViewController != null)
{
newObjectViewController.NewObjectAction.Active.SetItemValue("Replaced", false);
// The line below disables the Action button
// filterController.FullTextFilterAction.Enabled.SetItemValue(deactivateReason, false);
}
popupWindowAction.CustomizePopupWindowParams += CustomizeWindowPopup;
}
if (View.AllowEdit)
{
currentObjectController = Frame.GetController<ListViewProcessCurrentObjectController>();
if (currentObjectController != null)
{
currentObjectController.CustomProcessSelectedItem += EditObjectActionPopup;
}
}
}
}
protected override void OnDeactivated()
{
base.OnDeactivated();
if (newObjectViewController != null)
{
newObjectViewController.NewObjectAction.Active.RemoveItem("Replaced");
newObjectViewController = null;
}
if (popupWindowAction != null)
{
popupWindowAction.CustomizePopupWindowParams -= CustomizeWindowPopup;
}
if (currentObjectController != null)
{
currentObjectController.CustomProcessSelectedItem -= EditObjectActionPopup;
}
}
public T TypedObject { get; set; }
public DialogController DialogController { get; set; }
public abstract void AcceptAction_ExecuteCompleted(object sender, ActionBaseEventArgs e);
private void CancelAction_ExecuteCompleted(object sender, ActionBaseEventArgs e)
{
popupObjectSpace.Rollback(true);
TypedObject = IsAdding ? null : popupObjectSpace.GetObject(TypedObject);
}
private void EditObjectActionPopup(object sender, CustomProcessListViewSelectedItemEventArgs e)
{
TypedObject = e.InnerArgs.CurrentObject as T;
e.Handled = true;
popupWindowAction.OpenPopup();
}
}
This class is a helper subclass that enables triggering the PopupWindowShowAction from code. That is necessary for the edit action override.
public class QpPopupWindowShowActionBinding(PopupWindowShowAction action)
: PopupWindowShowActionBinding(action, new DummyActionControl())
{
public void TriggerPopup()
{
using (NewActionExecutionScope())
ShowPopupWindow();
}
}
I had to create a Dummy IActionControl to allow generating an action binding from code:
public class DummyActionControl : ISimpleActionControl
{
public void SetVisible(bool visible) {}
public void SetEnabled(bool enabled) {}
public void SetCaption(string caption) {}
public void SetToolTip(string toolTip) {}
public void SetImage(string imageName) {}
public void SetConfirmationMessage(string confirmationMessage) {}
public void SetShortcut(string shortcutString) {}
public void SetPaintStyle(ActionItemPaintStyle paintStyle) {}
public string ActionId { get; set; }
public object NativeControl { get; set; }
public event EventHandler NativeControlDisposed;
public event EventHandler<EventArgs> Execute;
}
And then finally, here is an example where I subclass the controller to create the add/edit popup window.
public class OrderActionController : QpPopupActionController<Order>
{
public Order Order
{
get => TypedObject;
set => TypedObject = value;
}
protected override void InitializeNewObject(Order typedObject)
{
var customer = (Customers)((PropertyCollectionSource) ((ListView)newObjectViewController.View).CollectionSource).MasterObject;
Order.Customer = popupObjectSpace.GetObject(customer);
}
public override void AcceptAction_ExecuteCompleted(object sender, ActionBaseEventArgs e)
{
if (IsAdding)
{
InventoryManager.RemoveInventory(popupObjectSpace, Order);
}
else
{
InventoryManager.AdjustInventory(popupObjectSpace, Order);
}
}
}
Upvotes: 0
Reputation: 111
It is impossible to make it work unless you set LinkNewObjectToParentImmediately to false under Program.cs . But in this case there won't be any relationship between objects. You can override action by adding new controller but it is also useless in your case because there must an existing customer to link new invoice to.
Upvotes: 1