Help with assembly refernces for hiding custom panel

Hello E10 Folks…

We wanted to take a stab at creating a BAQDataView on PartEntry. We were successful at getting this done on a custom panel. We then wanted to continue this and see if we could hide/show the added panel based on User Security Group membership. We utilized instruction found here on e10, but I think we don’t have a firm grasp on the assembly references. When we compile we get the following:

Compiling Custom Code …

----------errors and warnings------------

Error: CS0234 - line 95 (444) - The type or namespace name ‘SupplierPriceList’ does not exist in the namespace ‘Erp.UI.App.PartEntry’ (are you missing an assembly reference?)
Error: CS0234 - line 95 (444) - The type or namespace name ‘SupplierPriceList’ does not exist in the namespace ‘Erp.UI.App.PartEntry’ (are you missing an assembly reference?)
Error: CS0234 - line 114 (463) - The type or namespace name ‘UserFileDataSet’ does not exist in the namespace ‘Erp.BO’ (are you missing an assembly reference?)

** Compile Failed. **

SupplierPriceList is the name of our custom panel and we thought that was needed.
As for the UserFileDataSet, I am unsure of what is reference (or using) I should add.
Outside of the Native Assemblies, we added:
Ice.Adapters.UserFile
Ice.Contracts.BO.Userfile

Any help our guidance is much appreciated.

// **************************************************
// Custom code for PartForm
// Created: 4/22/2019 3:13:08 PM
// **************************************************

extern alias Erp_Contracts_BO_Part;
extern alias Erp_Contracts_BO_PartPlantSearch;
extern alias Erp_Contracts_BO_PO;
extern alias Erp_Contracts_BO_PartOnHandWhse;
extern alias Erp_Contracts_BO_Vendor;
extern alias Erp_Contracts_BO_VendorPPSearch;
extern alias Ice_Contracts_BO_UserFile;

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Erp.Adapters; 
using Erp.UI;
using Ice.Lib;
using Ice.Adapters;
using Ice.Lib.Customization;
using Ice.Lib.ExtendedProps;
using Ice.Lib.Framework;
using Ice.Lib.Searches;
using Ice.UI.FormFunctions;
using Ice.Lib.Broadcast;



public class Script
{
	// ** Wizard Insert Location - Do Not Remove 'Begin/End Wizard Added Module Level Variables'     
Comments! **
	// Begin Wizard Added Module Level Variables **

	// End Wizard Added Module Level Variables **

// Add Custom Module Level Variables Here **
BAQDataView baqViewSupplierPriceList;


public void InitializeCustomCode()
{
	// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
	// Begin Wizard Added Variable Initialization

	// End Wizard Added Variable Initialization

	// Begin Wizard Added Custom Method Calls

	// End Wizard Added Custom Method Calls
	CreateSupplierPriceListBAQView();
}

public void CreateSupplierPriceListBAQView()

{
	baqViewSupplierPriceList = new BAQDataView("SupplierPriceList");
	oTrans.Add("SupplierPriceListBAQ",baqViewSupplierPriceList);

	
	string pubBinding = "Part.PartNum";
	IPublisher pub = oTrans.GetPublisher(pubBinding);
			
	baqViewSupplierPriceList.SubscribeToPublisher(pub.PublishName, "VendPart_PartNum");
	
}

public void DestroyCustomCode()
{
	// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Object Disposal' lines **
	// Begin Wizard Added Object Disposal

	// End Wizard Added Object Disposal

	// Begin Custom Code Disposal

	// End Custom Code Disposal
}

private void PartForm_Load(object sender, EventArgs args)
{
	// Add Event Handler Code
	HideSupplierPriceListPanel();		
	
}

private void HideSupplierPriceListPanel()
{
	
	Ice.Core.Session userSession = (Ice.Core.Session)oTrans.Session; 
	if (!GetUserByID(userSession.UserID))
{            
		Erp.UI.App.PartEntry.SupplierPriceList sp_Panel = ((Erp.UI.App.PartEntry.SupplierPriceList)csm.GetNativeControlReference("f7952705-e201-472f-8da3-f33228bc6075"));
		Infragistics.Win.UltraWinDock.DockableWindow sp_PanelDockWindow = (Infragistics.Win.UltraWinDock.DockableWindow)sp_Panel.Parent;
		Infragistics.Win.UltraWinDock.DockableControlPane sp_PanelDockPane = (Infragistics.Win.UltraWinDock.DockableControlPane)sp_PanelDockWindow.Pane;
		sp_PanelDockPane.Close();
			
 }

}

private bool GetUserByID(string dcdUserID)
{
    bool isUserAccess = false;
    try
    {
        UserFileAdapter adapterUserFile = new UserFileAdapter(this.oTrans);
        adapterUserFile.BOConnect();
        bool result = adapterUserFile.GetByID(dcdUserID);
        if (result)
        {
            Erp.BO.UserFileDataSet.UserFileDataTable userDataTable = adapterUserFile.UserFileData.UserFile;
            if (Convert.ToBoolean(userDataTable.Rows[0]["SecurityMgr"]) || Convert.ToString(userDataTable.Rows[0]["GroupList"]).Contains("_Purchasing"))//Replace your User Group Code here
                isUserAccess = true;
        }
        adapterUserFile.Dispose();
    }
    catch (System.Exception ex)
    {
        ExceptionBox.Show(ex);
    }
    return isUserAccess;
}

The custom panel has a name of SupplierPriceList, but that’s not a base type in Epicor. I can see how that might be confusing in the Part form because types were created for all the panels and the names pretty much match. Take a look at the properties for the panel and copy/paste the type on the line where you’re declaring the sp_Panel variable in the HideSupplierPriceListPanel() method.

If it’s an EpiBasePanel like ours (likely), then your code will become:

Ice.Lib.Framework.EpiBasePanel sp_Panel = (Ice.Lib.Framework.EpiBasePanel)csm.GetNativeControlReference("f7952705-e201-472f-8da3-f33228bc6075");

As for the UserFileDataSet, it’s just a typo. It should be Ice instead of Erp.

Ice.BO.UserFileDataSet.UserFileDataTable userDataTable = adapterUserFile.UserFileData.UserFile;

Also, a quick note on adapters - you can wrap them in a using() statement to self-dispose the object instead of explicitly disposing later. If an error occurred in your current code between the BOConnect() and Dispose() methods, the adapter would be left in memory. Will it hurt anything if it’s not disposed? Probably not in this case, but it’s a good habit to get into so it doesn’t when you start dealing with larger data sets and/or calling adapters multiple times in an automated process.

private bool GetUserByID(string dcdUserID)
{
    bool isUserAccess = false;
    try
    {
        using (UserFileAdapter adapterUserFile = new UserFileAdapter(this.oTrans))
		{
			adapterUserFile.BOConnect();
			bool result = adapterUserFile.GetByID(dcdUserID);
			if (result)
			{
				Ice.BO.UserFileDataSet.UserFileDataTable userDataTable = adapterUserFile.UserFileData.UserFile;
				if (Convert.ToBoolean(userDataTable.Rows[0]["SecurityMgr"]) || Convert.ToString(userDataTable.Rows[0]["GroupList"]).Contains("_Purchasing"))//Replace your User Group Code here
					isUserAccess = true;
			}
        }
    }
    catch (System.Exception ex)
    {
        ExceptionBox.Show(ex);
    }
    return isUserAccess;
}

Thank you Jason.
I applied your well explained changes and the code compiles.

Moving on… I tried to test out the show/hide functionality by attaching this customization to the part menu and logging in with both a user who is (and is not) part of the security group that is associated with the show/hide logic.

The form is fine for a user with membership.
But when I launch the form with a user who is not part of the group (hide the custom panel) I get the dreaded: Object reference not set to an instance of an object.
I have cleared cache and done the few trick I know of, but this appears to be consistent accrose multiple PCs.

This could constitute a new thread. Your above answers definitely satisfies the question posed here…
Thanks again on that front.

Application Error

Exception caught in: mscorlib

Error Detail

Message: Exception has been thrown by the target of an invocation.
Inner Exception Message: Object reference not set to an instance of an object.
Program: CommonLanguageRuntimeLibrary
Method: InvokeMethod

Client Stack Trace

at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeScriptMethod(MethodInfo scriptMethod, Object[] parameters)
at Ice.Lib.Customization.CustomScriptMethodInvoker.InvokeCustomFormLoadIfExists(String methodName, Object sender, EventArgs e)
at Ice.Lib.Customization.CustomScriptManager.<>c__DisplayClass103_0.b__0()
at Ice.Lib.Customization.CustomScriptManager.TryActionShowExceptionBoxOrLogVerificationErrorIfException(Action action, String exceptionBoxTitle)

Inner Exception

Object reference not set to an instance of an object.

at Script.HideSupplierPriceListPanel()
at Script.PartForm_Load(Object sender, EventArgs args)

Well, the inner exception shows that the PartForm_Load method was called, which then called the HideSupplierPriceListPanel method, and the error occurred somewhere in there. Also, since you didn’t get the error with an authorized user, we can assume (for now) that only code that executes when the user doesn’t have rights could cause the issue. This limits it down to the sp_Panel, sp_PanelDockWindow, and sp_PanelDockPane declarations to debug.

I went ahead and tried hiding the panel from my previous screenshot with that code and it worked perfectly.

Are you 100% sure you have the correct EpiGuid value? You can see it in the properties of the panel. Copy and paste it to be sure.

If that value is correct and you still can’t figure out what’s going on, it is always possible to step through the custom code in Visual Studio. Or, if that’s a bit much for you, try adding some message boxes to pop up and let you know what areas of the code have executed successfully.

Thanks Jason,

It bombs on this…

sp_PanelDockPane.Close();

I set up messages before and after most of the lines in HideSupplierPriceListPanel() and when I comment out this one line, I don’t get the message.
I’ll keep plugging until I figure it out.

-JM