# Handheld Move Inventory Custom UI

**URL:** <https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320>\
**Category:** Epicor ERP 10\
**Tags:** handheld\
**Created:** [August 1, 2019, 2:11pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320 "2019-08-01T14:11:25Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 2:11pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/1 "2019-08-01T14:11:25Z")

</div>

I’m trying to create a UI customization that, when a user scans a lot number into the UD lot field, it finds the bin with the lot and puts the part, qty, first bin, and first whse code into the fields.  
I was trying to key into the scanLotTXT\_ADW field’s validated event and have it trigger from there, but I’m not sure how to get a new record/dataset to put the fields into.

![image](https://epiusers.help/uploads/default/original/3X/6/8/6804ccfa674c7ac7eb2002508740cd59b26e9a4c.png)

This is what I was going for (trying to create a new row in the view dataset and insert fields, but it throws errors left and right). Has anyone done something like this that could offer me some guidance?  
The below code, I was trying to get it to work with hard-coded data before I went further and used the dynamic data from whatever lot they scanned.

```cs
	private void scanLotTXT_ADW_Validated(object sender, System.EventArgs args)
	{
		// **Place Event Handling Code Here**
		EpiDataView edvMove = oTrans.Factory("view");
		var newRow = edvMove.dataView.AddNew();
		newRow.BeginEdit();
		newRow["PartNum"] = "S-160";
	    newRow["RowMod"] = "A";
		newRow["TransferQty"] = 2;
		newRow["FromWarehouseCode"] = "MAIN";
		newRow["FromBinNum"] = "TRK";
		newRow["TransferQtyUOM"] = "EA";
		newRow["FromLotNum"] = this.scanLotTXT_ADW.Value;
		newRow["Company"] = "ISI"; 
		newRow.EndEdit();
		oTrans.NotifyAll();
		
		CallInvTransferAdapterGetTransferRecordMethod();
	}

	private void CallInvTransferAdapterGetTransferRecordMethod()
	{
		try
		{
			// Declare and Initialize EpiDataView Variables
			// Declare and create an instance of the Adapter.
			InvTransferAdapter adapterInvTransfer = new InvTransferAdapter(this.oTrans);
			adapterInvTransfer.BOConnect();

			// Declare and Initialize Variables
			// TODO: You may need to replace the default initialization with valid values as required for the BL method call.
			string iPartNum = "S-160";
			string uomCode = "";

			// Call Adapter method
			Erp.BO.InvTransferDataSet dsInvTransfer = adapterInvTransfer.GetTransferRecord(iPartNum, uomCode);

			// Cleanup Adapter Reference
			adapterInvTransfer.Dispose();

		} catch (System.Exception ex)
		{
			ExceptionBox.Show(ex);
		}
	}

```

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 2:25pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/2 "2019-08-01T14:25:41Z")

</div>

So what I’ve done before is once they scan the lot, use a BAQ to find it, once the results are found you need to then mimic the trace or trigger the standard form events.  
For example in this form they call the

```cs
oTrans.OnValidateKeyField(tbPartNum)

```

where tbPartNum is the PartNum textbox, so do that, fill in the PartNum textbox.text property then call oTrans.OnValidateKeyField(tbPartNum)

This will (should) trigger all the standard lookup stuff, then just populate the Whse , Bin and Lot in the dataview like normal.

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 2:48pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/3 "2019-08-01T14:48:55Z")

</div>

How do you go about finding that form call if I were to do other things?

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 3:01pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/4 "2019-08-01T15:01:54Z")

</div>

Say what now?

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 3:04pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/5 "2019-08-01T15:04:40Z")

</div>

How did you come up with this: oTrans.OnValidateKeyField(tbPartNum)?  
If I needed to find that info myself, how would I go about it?

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 3:06pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/6 "2019-08-01T15:06:07Z")

</div>

You buy the SDK 😛  
Or use Reflection dnSpy is your friend

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 3:27pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/7 "2019-08-01T15:27:31Z")

</div>

> [@josecgomez](#):
>
> You buy the SDK 😛

![](https://media1.tenor.com/images/5b3ac3a3d045fe6a60c87a73910ca4b4/tenor.gif?itemid=4679471)

---

<div class="post-metadata">

**Author:** ![markdamen](https://www.epiusers.help/user_avatar/www.epiusers.help/markdamen/32/54917_2.png) [@markdamen](https://www.epiusers.help/u/markdamen)\
**Post date:** [August 1, 2019, 3:29pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/8 "2019-08-01T15:29:15Z")

</div>

![image](https://epiusers.help/uploads/default/original/3X/0/c/0c8aa6b00cd71011eef00c7fc3cde56d28260504.png)

Hi Aaron

I was previously doing this with some BPMs, but when upgrading to 10.2 changed it out for a screen customisation because Epicor changed the signatures on some of the methods that the BPMs were attached to.

This should do what you ask 🙂

```cs
// **************************************************
// Custom code for HHInvTransferForm
// Created: 04/11/2016 22:52:40
// **************************************************
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 Erp.Proxy.BO;

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 **
	
	private EpiBaseAdapter oTrans_adapter;

	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

		this.txtMyLot.Leave += new System.EventHandler(this.txtMyLot_Leave);
		this.HHInvTransferForm.AfterToolClick += new Ice.Lib.Framework.AfterToolClickEventHandler(this.HHInvTransferForm_AfterToolClick);
		this.oTrans_adapter = ((EpiBaseAdapter)(this.csm.TransAdaptersHT["oTrans_adapter"]));
		
		// End Wizard Added Custom Method Calls
	}

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

		this.txtMyLot.Leave -= new System.EventHandler(this.txtMyLot_Leave);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal
	    this.HHInvTransferForm.AfterToolClick -= new Ice.Lib.Framework.AfterToolClickEventHandler(this.HHInvTransferForm_AfterToolClick);
		// End Custom Code Disposal
	}

	private void txtMyLot_Leave(object sender, System.EventArgs args)
	{
		EpiTextBox txtMyLot = (EpiTextBox)csm.GetNativeControlReference("827a4923-705b-4a91-b03a-3fc7add83cf8");
		EpiTextBox txtMyFromLot = (EpiTextBox)csm.GetNativeControlReference("e2f83141-e64e-4d72-ae69-6f17d8b31e96");
		EpiTextBox txtMyToLot = (EpiTextBox)csm.GetNativeControlReference("d4902d27-86a8-4474-ad1a-5e13605316e5");
		EpiTextBox txtPart = (EpiTextBox)csm.GetNativeControlReference("8f54f627-4a40-4e54-8a2a-fe39fccf325f");
		
		//EpiTextBox txtFromWhse = (EpiTextBox)csm.GetNativeControlReference("d4e998d4-fbdf-4868-ba34-70ff1dd9dbf4");
		//EpiTextBox txtFromBin = (EpiTextBox)csm.GetNativeControlReference("e4286565-e4c0-4e9e-ae3d-3ceb8e0bcc2d");
		
		EpiNumericEditor numMyQty = (EpiNumericEditor)csm.GetNativeControlReference("e6615dea-11a8-4a39-9e0c-8c8894160e96");
		
		if(txtMyLot.Text.Length >= 8)
		{
			txtPart.Text = txtMyLot.Text.Substring(0,8) ;
			txtPart.Select();
			txtMyFromLot.Select();
			txtMyFromLot.Text = txtMyLot.Text;
			txtMyToLot.Select();
			txtMyToLot.Text = txtMyLot.Text;
			numMyQty.Select();

			string strPartNum = txtPart.Text;
			string strLotNum = txtMyLot.Text;
						
			try
			{
				var session = (Ice.Core.Session)oTrans.Session; 
				var bo = WCFServiceSupport.CreateImpl<PartBinSearchImpl>(session, PartBinSearchImpl.UriPath);
				var ds = bo.GetPartBinByLot(strPartNum, strLotNum);
						
				var strExpr = "QtyOnHand > 0";
				var strSort = "";
				
				var foundRows = ds.Tables[0].Select(strExpr, strSort);  
				
				EpiDataView edvView = (EpiDataView)(oTrans.EpiDataViews["view"]);
				edvView.dataView[edvView.Row]["FromWarehouseCode"] = foundRows[0]["WhseCode"].ToString();		
				edvView.dataView[edvView.Row]["FromBinNum"] = foundRows[0]["BinNum"].ToString();
			
			} catch (Exception ex) {
				MessageBox.Show("Cannot locate PartBin record: " + ex.Message) ;
			}
		//oTrans.ViewRow["FromWarehouseCode"] = "DEFBIN";
		//((InvTransferAdapter)oTrans_adapter).ChangeFromWhse(((InvTransferAdapter)oTrans_adapter).InvTransferData);
		//oTrans.NotifyAll();
		
		}		
		
	}

	private void HHInvTransferForm_Load(object sender, EventArgs args)
	{
		// Add Event Handler Code

		EpiDataView evContext = ((EpiDataView)(oTrans.EpiDataViews["CallContextClientData"])); 
	    lblCustomisationID.Text = "CustomisationID - " + evContext.CurrentDataRow["CustomizationId"].ToString();

		EpiTextBox txtMyLot = (EpiTextBox)csm.GetNativeControlReference("827a4923-705b-4a91-b03a-3fc7add83cf8");
		txtMyLot.CharacterCasing = CharacterCasing.Upper;

		txtMyLot.Select();
	}

	private void HHInvTransferForm_AfterToolClick(object sender, Ice.Lib.Framework.AfterToolClickEventArgs args)
	{
	   		
		//MessageBox.Show(args.Tool.Key);
		switch (args.Tool.Key)
	  	{
	    		case "ClearTool":
	       		EpiTextBox txtMyLot = (EpiTextBox)csm.GetNativeControlReference("827a4923-705b-4a91-b03a-3fc7add83cf8");
	    	   	txtMyLot.Text = String.Empty;
	       		break;
		  }
	}

}

```

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 5:57pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/9 "2019-08-01T17:57:49Z")

</div>

How do I get it to focus the new lot number field and stick?  
I tried setting scanLotTXT\_ADW.Focus() and scanLotTXT\_ADW.Select() on both the initialize and load events, but what seems to happen is it does focus the field, then immediately focuses the Part field right after. I can’t get that Part focus to stop.

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 6:25pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/10 "2019-08-01T18:25:09Z")

</div>

Yeah I’m willing to be they hard coded that… @jgiese.wci how did we fix this?

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 6:29pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/11 "2019-08-01T18:29:33Z")

</div>

Yup they hard coded it everywhere!  
 ![image](https://epiusers.help/uploads/default/original/3X/0/3/032efd7966ac54256e38111b4aae3d58c495aca6.png)

![image](https://epiusers.help/uploads/default/original/3X/d/3/d37b1caadd22dfebb38ce4486311bd7c51137b40.png)

You could try not making that PartNum field a tab stop but I doubt it would work.  
You can also use a timer but that’s gross

Try setting the TabIndex to 1 on your Lot and the parNum tab index to something higher.

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 6:32pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/12 "2019-08-01T18:32:20Z")

</div>

> [@josecgomez](#):
>
> Try setting the TabIndex to 1 on your Lot and the parNum tab index to something higher.

I tried that. Same thing happens.

---

<div class="post-metadata">

**Author:** ![jgiese.wci](https://www.epiusers.help/user_avatar/www.epiusers.help/jgiese.wci/32/51553_2.png) [@jgiese.wci](https://www.epiusers.help/u/jgiese.wci)\
**Post date:** [August 1, 2019, 6:36pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/13 "2019-08-01T18:36:04Z")

</div>

It’s hacky but you can try to use the GotFocus event on the part field and then pass focus to the lot field. You would need a flagged bypass on the click event, tab event, or other events for the part field when you actually want to get into that field. Again super hacky but maybe better than a timer also ew…

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 6:37pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/14 "2019-08-01T18:37:35Z")

</div>

Hah–that’s exactly the direction I was working on:

```cs
	private void part_GotFocus(object sender, System.EventArgs args)
	{
		if( initFlag )
		{
			initFlag = false;
			scanLotTXT_ADW.Focus();
		}
	}

```

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 6:45pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/15 "2019-08-01T18:45:05Z")

</div>

No bueno.  
I actually had to change it to the Part.Enter event instead of GotFocus to get it to fire each time, but doing either scanLotTXT\_ADW.Select() or .Focus() doesn’t seem to actually select the control…

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 6:47pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/16 "2019-08-01T18:47:03Z")

</div>

I’ve used a timer for this in the past I hate it … but it works…

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 7:01pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/17 "2019-08-01T19:01:30Z")

</div>

Hmm, so the timer more or less works, but I’m still having issues with the select/focus events. They don’t seem to be doing anything.

 ![MoveInventory](https://epiusers.help/uploads/default/original/3X/2/6/26bd87e72dbb77eb43317b436766d0b791654478.gif)

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 7:02pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/18 "2019-08-01T19:02:58Z")

</div>

I mean .Focus() will work (should) but it may get taken away by something else that epicor has hard coded.  
Have the timer wait 5 seconds after the form load just for a test. And see if the focus stays after that point.

---

<div class="post-metadata">

**Author:** ![hmwillett](https://www.epiusers.help/user_avatar/www.epiusers.help/hmwillett/32/93207_2.png) [@hmwillett](https://www.epiusers.help/u/hmwillett)\
**Post date:** [August 1, 2019, 7:05pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/19 "2019-08-01T19:05:11Z")

</div>

.Focus() doesn’t seem to do anything at all.  
If I set .Focus(), after 5 (and even 10) seconds, the Part field still has the cursor.  
If I set it to .Select(), after 5 seconds, the cursor disappears from all fields as shown in the above gif.

---

<div class="post-metadata">

**Author:** ![josecgomez](https://www.epiusers.help/user_avatar/www.epiusers.help/josecgomez/32/55731_2.png) [@josecgomez](https://www.epiusers.help/u/josecgomez)\
**Post date:** [August 1, 2019, 7:20pm UTC](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320/20 "2019-08-01T19:20:03Z")

</div>

Ah right!, sorry I forgot  
Timer’s run in a different thread so you have to “Invoke” them into the right thread. Try this in your Timed Event

```auto
using System.Threading;
private void OnTimedEvent(Object source, ElapsedEventArgs e) {
 yourTextBox.Invoke((ThreadStart) delegate() {
  yourTextBox.Focus();
 });
}

```

[Next page](https://www.epiusers.help/t/handheld-move-inventory-custom-ui/58320.md?page=2)
