BAQ Dataview linked to unbound controls?

Hi All!
I am working to optimize one of my dashboards. My goal is to have a dashboard with one ultragrid (not native), and to use that ultragrid to display either the results of one BAQ or another, based on whether or not the part/rev is checked out.

I setup a new dashboard with an empty tracker view, and my updatable BAQ. I’d like to ignore the native grid added to the dashboard, and work only on my custom ultragrid. So I put the native grid into a separate tab, and use the tracker view in full screen.

To the tracker view I added a few unbound controls. My part number text box, and a combo box for selecting the revision. Below that I have a button to initiate the search, and an ultra grid to display the results.

My question is in defining the epibinding and updating the ultragrid. The code I have posted here returns all the rows of the BAQ, not just the part/rev I want. I think it is because of how I link the part and rev fields to their underlying BAQs. I have done this successfully with bound fields. What’s the best way to link an ultragrid to a BAQ with two unbound criteria fields?

Here is my complete customization code, as well as the dashboard, BAQ and customization files if you want to try it yourself.

Thank you for your time!
Nate

// **************************************************
// Custom code for MainController
// Created: 5/6/2021 9:17:20 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Ice.BO;
using Ice.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;
using System.Reflection;

public class Script
{
	public BAQCombo cmbpartrev;
	public EpiTextBox txtPart;
	BAQDataView ecoRevOpsBAQDV;
	BAQDataView partRevOpsBAQDV;
	// ** 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 **

	public void InitializeCustomCode()
	{
		
CreatePartRevOpsBAQDV();
		// ** 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.txtPartNum.ValueChanged += new System.EventHandler(this.txtPartNum_ValueChanged);
		this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
		// End Wizard Added Custom Method Calls
		txtPart = (EpiTextBox)csm.GetNativeControlReference("85eb5e53-1a90-4a85-8277-3321f576de88");
	}

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

		this.txtPartNum.ValueChanged -= new System.EventHandler(this.txtPartNum_ValueChanged);
		this.btnSearch.Click -= new System.EventHandler(this.btnSearch_Click);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void RefreshMe()
	{			
		MainController.AppControlPanel.HandleToolClick("RefreshTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["RefreshTool"], null));
	}

	private void ClearMe()
	{			
		MainController.AppControlPanel.HandleToolClick("ClearTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["ClearTool"], null));
	}

	public void CreateEcoRevOpsBAQDV()
	{
		ecoRevOpsBAQDV = new BAQDataView("getPartRevOpECO"); //baq name
		oTrans.Add("EcoRevOpsBAQDV",ecoRevOpsBAQDV); 
		UpdateEcoRevOpsBAQDV();	
	}

	public void UpdateEcoRevOpsBAQDV()
	{
		if (txtPartNum.Value != null)
		{	
		string pub1Binding = txtPartNum.Text; //Native form linking field 1
		IPublisher pub1 = oTrans.GetPublisher(pub1Binding);
		if(pub1==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub1Binding, pubName);
			pub1 = oTrans.GetPublisher(pub1Binding);
		} 
		if(pub1 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub1.PublishName, "ECORev_PartNum"); //BAQ linking field 1

		string pub2Binding = cmbpartrev.Text; //Native form linking field 2
		IPublisher pub2 = oTrans.GetPublisher(pub2Binding);
		if(pub2==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub2Binding, pubName);
			pub2 = oTrans.GetPublisher(pub2Binding);
		} 
		if(pub2 !=null) 
			ecoRevOpsBAQDV.SubscribeToPublisher(pub2.PublishName, "ECORev_RevisionNum");//BAQ linking field 2	
		}
	}

	public void CreatePartRevOpsBAQDV()
	{
		partRevOpsBAQDV = new BAQDataView("EditAnyOp"); //baq name
		oTrans.Add("PartRevOpsBAQDV",partRevOpsBAQDV); 
		UpdatePartRevOpsBAQDV();
	}
	
	public void UpdatePartRevOpsBAQDV()
	{
		
		if (txtPartNum.Value != null)
		{
		string pub1Binding = txtPartNum.Text; //Native form linking field 1
		IPublisher pub1 = oTrans.GetPublisher(pub1Binding);
		if(pub1==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub1Binding, pubName);
			pub1 = oTrans.GetPublisher(pub1Binding);
		} 
		if(pub1 !=null) 
			partRevOpsBAQDV.SubscribeToPublisher(pub1.PublishName, "PartRev_PartNum"); //BAQ linking field 1

		string pub2Binding = cmbpartrev.Text; //Native form linking field 2
		IPublisher pub2 = oTrans.GetPublisher(pub2Binding);
		if(pub2==null) 
		{ 
			string pubName = Guid.NewGuid().ToString();
			oTrans.PublishColumnChange(pub2Binding, pubName);
			pub2 = oTrans.GetPublisher(pub2Binding);
		} 
		if(pub2 !=null) 
			partRevOpsBAQDV.SubscribeToPublisher(pub2.PublishName, "PartRev_RevisionNum");//BAQ linking field 2
		}
	}

	private void getRevs()
	{
		cmbpartrev = (Ice.Lib.Framework.BAQCombo)csm.GetNativeControlReference("67f0a748-4944-468b-96b0-cce76dfb5588");

		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("getPartRev");
		qeds.ExecutionParameter.Clear();

		qeds.ExecutionParameter.AddExecutionParameterRow("part", txtPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");

		dqa.ExecuteByID("getPartRev", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbpartrev.DataSource = dqa.QueryResults.Tables["Results"];
			cmbpartrev.DisplayMember = "PartRev_RevisionNum";
			cmbpartrev.ValueMember = "PartRev_RevisionNum";
			oTrans.NotifyAll();
		}
	}

	private void CheckForCheckedOut()
	{
		if (partRevOpsBAQDV == null) {CreatePartRevOpsBAQDV();}
		if (partRevOpsBAQDV.dataView.Count > 0) //Rev is checked out!
		{
		//Show ECORev in grid
		MessageBox.Show("Checked Out!");
		if(ecoRevOpsBAQDV == null) {CreateEcoRevOpsBAQDV();}
		UpdateEcoRevOpsBAQDV();
	
	epiUltraGridC1.EpiBinding = "EcoRevOpsBAQDV";
		epiUltraGridC1.Refresh();
		MethodInfo mi = ecoRevOpsBAQDV.GetType().GetMethod("InvokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
		mi.Invoke(ecoRevOpsBAQDV, new object[]{ true });
		}
		else
		{
		//Show PartRev in grid
		MessageBox.Show("Not Checked Out!");
		UpdatePartRevOpsBAQDV();
		epiUltraGridC1.EpiBinding = "PartRevOpsBAQDV";
		epiUltraGridC1.Refresh();
		MethodInfo mi2 = partRevOpsBAQDV.GetType().GetMethod("InvokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
		mi2.Invoke(partRevOpsBAQDV, new object[]{ true });
		}
	}

	private void txtPartNum_ValueChanged(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		getRevs();
	}

	private void btnSearch_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		CheckForCheckedOut();
		epiUltraGridC1.Refresh();
	}
}

EditAnyOp_New.dbd (509.2 KB)
EditAnyOp.baq (299.7 KB) getPartRevOpECO.baq (23.4 KB) getPartRev.baq (13.5 KB) App.EditAnyOp_New.MainController_Customization_Custom1_CustomExport.xml (92.8 KB)

This may not be “correct”, but if you made two EpiUltraGrids bound to your two BAQs, then you could show/hide each one based on your logic.

4 Likes

What Jason proposed seems like a neat idea

Also you don’t have to have unbound controls simply make your own EpiDataView

1 Like

You make it sound so easy!
So I need to create two EDVs, one for each of my BAQs. Something like this?

EpiDataView partOps = new EpiDataView();
EpiDataView ecoOps = new EpiDataView();

Then I need to pull the columns and rows from my BAQs and stuff them into these data views? That part I am not clear on.

Once I have the two EDVs created, I think I can just switch the EpiBinding for the ultra grid, right?

Well you just need a DataView for your “Tracker” view
something like

//Class Level
    DataTable dt;
    EpiDataView myDV;
     
//Initialize Code
 
myDV = new EpiDataView();
dt = new DataTable();
dt.Columns.Add(new DataColumn("Mike"));
dt.Columns.Add(new DataColumn("Peter"));
dt.Columns.Add(new DataColumn("SysRowID", typeof(Guid)));
 
 
/*
This will allow you to add a row to the current dataview 
*/
 
var dr = dt.NewRow();
dr["SysRowID"]=Guid.NewGuid();
dr["Mike"]="Mike";
dt.Rows.Add(dr);
 
myDV.dataView= dt.DefaultView;
oTrans.Add("myDV", myDV);
 
myDV.Notify(new EpiNotifyArgs(oTrans, myDV.Row, EpiTransaction.NotifyType.Initialize));

That gives you a dataview named “myDv” that you can bind controls to

Then you can use Pub Sub to subscribe your child view (grid) to this. I’m assuming that grid is populated via a BAQDataView? How is it populated?

3 Likes

The grid is not populated when the form launches. I am trying to set the epibinding of the grid to one of two baqs (in the form of an EDV?) depending on some criteria. The grid should be populated after I run CreatePartRecOpsBAQDV(), and UpdatePartRevOpsBAQDV().

You would then need to create a BAQDataView to tie thatr grid to, then use pub sub to subscribe the BAQDataView to the newly creted EpiDataView above.

I’ll see if I can throw together an example.

1 Like

here you go @NateS hope this helps

Here’s the code to go along with it

// **************************************************
// Custom code for UD103Form
// Created: 5/13/2021 11:15:16 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Ice.BO;
using Ice.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;

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 **
	DataTable dtpDupParts;
	EpiDataView dvDupParts;
	BAQDataView bdvFromPBInfo, bdvToPBInfo;

	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
		SetupCustomDV();
	}

	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
	}
	public void SetupCustomDV()
	{
		dtpDupParts = new DataTable();
		var colFromPart = new DataColumn("FromPart");
		colFromPart.ExtendedProperties["Like"]="Part.PartNum";	
		dtpDupParts.Columns.Add(colFromPart);
		dtpDupParts.Columns.Add(new DataColumn("SysRowId",typeof(Guid)));
		
		var dr = dtpDupParts.NewRow();
		dr["SysRowId"] = Guid.NewGuid();
		dtpDupParts.Rows.Add(dr);

		dvDupParts = new EpiDataView();
		dvDupParts.dataView = dtpDupParts.DefaultView;
		oTrans.Add("TrackerView",dvDupParts);

		bdvFromPBInfo = new BAQDataView("PartDeDup_partbininfo");
		oTrans.Add("FromPartBinView",bdvFromPBInfo);

		var fromPBBinding= "TrackerView.FromPart";
		oTrans.PublishColumnChange(fromPBBinding,"FromPBPub");
		var fromPub = oTrans.GetPublisher(fromPBBinding);
		bdvFromPBInfo.SubscribeToPublisher(fromPub.PublishName,"PartBin_PartNum");
	}
}




6 Likes

Jose! This is incredible! Thank you for taking time to post this! Having the simple explanation for each line is really helpful.

I guess my question is, can this be done with a single grid? Can the epibinding for a single grid be changed during runtime? I just want to use one grid, and switch the epibinding. If the part/rev is checked out, then I want to use my ECORev BAQ, and if there are no parts checked out I want to use my PartRev UBAQ.

Thanks again!
Nate

As @Jason_Woods said :upside_down_face:, have two grids, and just hide / show them as needed (much easier)

1 Like

Hey! That suggestions sounds familiar! :wink:

2 Likes

It’s not that I don’t appreciate your suggestion, I just want to know if this is possible, not if it is easy.

Can an UltraGrid’s EpiBinding be changed during runtime at all? I have tried several methods and it seems like the binding that I set in the ultragrid properties is the only one that sticks. I can change the epibinding, but it doesn’t seem to affect the ultragrids contents. Here is some code to tear up:

// **************************************************
// Custom code for MainController
// Created: 5/6/2021 9:17:20 AM
// **************************************************
using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Ice.BO;
using Ice.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;
using System.Reflection;
using Infragistics.Shared;
using Infragistics.Win;
using Infragistics.Win.UltraWinGrid;

public class Script
{
	public BAQCombo cmbpartrev;
	
	DataTable dtPartRevOps; // DAta table to hold the data from one of the BAQ dataviews.
	EpiDataView dvPartRevOps; // Custom EDV
	BAQDataView bdvEco, bdvPart;

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

	private EpiDataView edvPartRevOps;
	// End Wizard Added Module Level Variables **

	// Add Custom Module Level Variables Here **

	public void InitializeCustomCode()
	{
		SetupECODV();
		SetupPartDV();
		epiUltraGridC1.Text = "";
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
		// Begin Wizard Added Variable Initialization

		this.edvPartRevOps = ((EpiDataView)(this.oTrans.EpiDataViews["PartRevOps"]));
		// End Wizard Added Variable Initialization

		// Begin Wizard Added Custom Method Calls

		this.cmbRevNum.Leave += new System.EventHandler(this.cmbRevNum_Leave);
		this.txtPartNum.Leave += new System.EventHandler(this.txtPartNum_Leave);
		this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
		// 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.cmbRevNum.Leave -= new System.EventHandler(this.cmbRevNum_Leave);
		this.edvPartRevOps = null;
		this.txtPartNum.Leave -= new System.EventHandler(this.txtPartNum_Leave);
		this.btnSearch.Click -= new System.EventHandler(this.btnSearch_Click);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void RefreshMe()
	{			
		MainController.AppControlPanel.HandleToolClick("RefreshTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["RefreshTool"], null));
	}

	private void ClearMe()
	{			
		MainController.AppControlPanel.HandleToolClick("ClearTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["ClearTool"], null));
	}

	public void SetupECODV()
 // Creates the view into EcoRev (BAQ = getPartRevOpECO)
	{
		dtPartRevOps = new DataTable(); //instantiate DT
		
		var colMyPart = new DataColumn("Part"); // inst column
		colMyPart.ExtendedProperties["Like"]="Part.PartNum";	//add like for right click open with
		dtPartRevOps.Columns.Add(colMyPart); // add custom column to DT (repeat for all columns)
		
		var colMyRev = new DataColumn("Rev"); // inst column
		dtPartRevOps.Columns.Add(colMyRev); // add custom column to DT (repeat for all columns)
		
		dtPartRevOps.Columns.Add(new DataColumn("SysRowId",typeof(Guid))); // add guid column to DT (required)
		
		var dr = dtPartRevOps.NewRow(); //inst a new row
		dr["SysRowId"] = Guid.NewGuid(); // just set the guid for the new row
		dtPartRevOps.Rows.Add(dr); // add the row to the DT to enable fields in the table

		dvPartRevOps = new EpiDataView(); //inst the EDV
		dvPartRevOps.dataView = dtPartRevOps.DefaultView; // set the EDV to the default view of the DT created above (default view is unfiltered view of entire DT)
		oTrans.Add("OpsList",dvPartRevOps); // adds the EDV to the binding list

		bdvEco = new BAQDataView("getPartRevOpECO"); //inst the BDV
		oTrans.Add("EcoRevOps",bdvEco); //add the BDV to the binding list (this is an unfiltered BDV. Filter the BDV with Pub/Sub)

		var fromPubPart= "OpsList.Part"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubPart,"FromPubPart"); //publish the value to otrans
		var fromPub = oTrans.GetPublisher(fromPubPart); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvEco.SubscribeToPublisher(fromPub.PublishName,"ECORev_PartNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.

		var fromPubRev= "OpsList.Rev"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubRev,"FromPubRev"); //publish the value to otrans
		var fromPub2 = oTrans.GetPublisher(fromPubRev); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvEco.SubscribeToPublisher(fromPub2.PublishName,"ECORev_RevisionNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
	}
	
	public void SetupPartDV()
 // creates the view into PartRev (BAQ = EditAnyOp)
	{
		dtPartRevOps = new DataTable(); //instantiate DT
		
		var colMyPart = new DataColumn("Part"); // inst column
		colMyPart.ExtendedProperties["Like"]="Part.PartNum";	//add like for right click open with
		dtPartRevOps.Columns.Add(colMyPart); // add custom column to DT (repeat for all columns)
		
		var colMyRev = new DataColumn("Rev"); // inst column
		dtPartRevOps.Columns.Add(colMyRev); // add custom column to DT (repeat for all columns)
		
		dtPartRevOps.Columns.Add(new DataColumn("SysRowId",typeof(Guid))); // add guid column to DT (required)
		
		var dr = dtPartRevOps.NewRow(); //inst a new row
		dr["SysRowId"] = Guid.NewGuid(); // just set the guid for the new row
		dtPartRevOps.Rows.Add(dr); // add the row to the DT to enable fields in the table

		dvPartRevOps = new EpiDataView(); //inst the EDV
		dvPartRevOps.dataView = dtPartRevOps.DefaultView; // set the EDV to the default view of the DT created above (default view is unfiltered view of entire DT)
		oTrans.Add("OpsList1",dvPartRevOps); // adds the EDV to the binding list

		bdvPart = new BAQDataView("EditAnyOp"); //inst the BDV
		oTrans.Add("PartRevOps",bdvPart); //add the BDV to the binding list (this is an unfiltered BDV. Filter the BDV with Pub/Sub)

		var fromPubPart1= "OpsList1.Part"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubPart1,"FromPubPart1"); //publish the value to otrans
		var fromPub1a = oTrans.GetPublisher(fromPubPart1); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvPart.SubscribeToPublisher(fromPub1a.PublishName,"PartRev_PartNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
		
		var fromPubRev1= "OpsList1.Rev"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubRev1,"FromPubRev1"); //publish the value to otrans
		var fromPub2a = oTrans.GetPublisher(fromPubRev1); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvPart.SubscribeToPublisher(fromPub2a.PublishName,"PartRev_RevisionNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
	}

	private void FilterBAQDataView(BAQDataView iBaqView, string iWhereClause)
	{
	    iBaqView.AdditionalFilter = iWhereClause;
	    iBaqView.dataView.RowFilter = iWhereClause;
	    iBaqView.Notify(new EpiNotifyArgs(oTrans, 0, EpiTransaction.NotifyType.Initialize));		
		//not sure if code below is needed...
		MethodInfo mi = iBaqView.GetType().GetMethod("InvokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
		mi.Invoke(iBaqView, new object[]{ true });
	}

	private void CheckForCheckedOut()
	{
		FilterBAQDataView(bdvEco,  "ECORev_PartNum = '"  + txtPartNum.Text + "' AND ECORev_RevisionNum = '" +  cmbRevNum.Text + "'");
		FilterBAQDataView(bdvPart, "PartRev_PartNum = '" + txtPartNum.Text + "' AND PartRev_RevisionNum = '" + cmbRevNum.Text + "'");
		if (bdvEco.dataView.Count > 0)
		{ //Show ECORev
			MessageBox.Show("Checked Out!");
			epiUltraGridC1.EpiBinding = "EcoRevOps";
			epiUltraGridC1.Text = epiUltraGridC1.EpiBinding.ToString();
			epiUltraGridC1.Refresh();
			txtPartNum.EpiBinding = "OpsList.Part";
			cmbRevNum.EpiBinding = "OpsList.Rev";
		}
		else //Show PartRev
		{
			MessageBox.Show("Not Checked Out!");
			epiUltraGridC1.EpiBinding = "PartRevOps";
			epiUltraGridC1.Text = epiUltraGridC1.EpiBinding.ToString();
			epiUltraGridC1.Refresh();
			txtPartNum.EpiBinding = "OpsList1.Part";
			cmbRevNum.EpiBinding = "OpsList1.Rev";
		}
	}
	
	private void getRevs()
	{
		cmbpartrev = (Ice.Lib.Framework.BAQCombo)csm.GetNativeControlReference("67f0a748-4944-468b-96b0-cce76dfb5588");
		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("getPartRev");
		qeds.ExecutionParameter.Clear();
		qeds.ExecutionParameter.AddExecutionParameterRow("part", txtPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");
		dqa.ExecuteByID("getPartRev", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbpartrev.DataSource = dqa.QueryResults.Tables["Results"];
			cmbpartrev.DisplayMember = "PartRev_RevisionNum";
			cmbpartrev.ValueMember = "PartRev_RevisionNum";
			//oTrans.NotifyAll();
		}
	}


	private void txtPartNum_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if(txtPartNum.Text != "") 
		{
		getRevs();
		}
	}

	private void cmbRevNum_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		//MessageBox.Show("Updating grid!");
		if (txtPartNum.Text != "")
		{
			if (cmbRevNum.Text != "")
			{
				CheckForCheckedOut();
			}
		}
	}

	private void btnSearch_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
	}
}

I mean you probably can, (I’ve never tried) because as Confucius says “Don’t use a cannon to kill a mosquito”

I’m certain it is possible (almost anything is given enough time and money) :stuck_out_tongue: but… KISS is my philosophy these days

1 Like

image

1 Like

OK ok, Ill give up on trying to use one ultragrid. I have two grids in my dashboard and they work ok. However I cant add a “AfterRowChange” event to either of my custom ultra grids. If I add the event using the wizard, I get this message on compile:

Error: CS1061 - line 123 (728) - 'Script' does not contain a definition for 'PartRevOps_Row' and no extension method 'PartRevOps_Row' accepting a first argument of type 'Script' could be found (are you missing a using directive or an assembly reference?)

In the past I have used this event without any issues. However, that was when I was using a native grid. Now I am using two custom grids. What am I missing?
Here is code:

// **************************************************
// Custom code for MainController
// Created: 5/6/2021 9:17:20 AM
// **************************************************

extern alias Erp_Adapters_PartRevSearch;
extern alias Erp_Adapters_EngWorkBench;

using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Windows.Forms;
using Ice.BO;
using Ice.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;
using System.Reflection;
using Infragistics.Shared;
using Infragistics.Win;
using Infragistics.Win.UltraWinGrid;



public class Script
{
	public BAQCombo cmbpartrev;
	
	DataTable dtPartRevOps; // DAta table to hold the data from one of the BAQ dataviews.
	EpiDataView dvPartRevOps; // Custom EDV
	BAQDataView bdvEco, bdvPart;

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

	private EpiDataView edvPartRevOps;
	private EpiDataView edvEcoRevOps;

	// End Wizard Added Module Level Variables **

	// Add Custom Module Level Variables Here **

	public void InitializeCustomCode()
	{
		SetupECODV();
		SetupPartDV();
		// ** Wizard Insert Location - Do not delete 'Begin/End Wizard Added Variable Initialization' lines **
		// Begin Wizard Added Variable Initialization
		this.edvPartRevOps = ((EpiDataView)(this.oTrans.EpiDataViews["PartRevOps"]));
		this.edvEcoRevOps = ((EpiDataView)(this.oTrans.EpiDataViews["EcoRevOps"]));
		this.PartRevOps_Row.EpiRowChanged += new EpiRowChanged(this.PartRevOps_AfterRowChange);
		// End Wizard Added Variable Initialization
		// Begin Wizard Added Custom Method Calls
		this.cmbRevNum.Leave += new System.EventHandler(this.cmbRevNum_Leave);
		this.txtPartNum.Leave += new System.EventHandler(this.txtPartNum_Leave);
		this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);
		this.btnEditCheckOut.Click += new System.EventHandler(this.btnEditCheckOut_Click);
		this.btnEditCheckIn.Click += new System.EventHandler(this.btnEditCheckIn_Click);
		// 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.cmbRevNum.Leave -= new System.EventHandler(this.cmbRevNum_Leave);
		this.edvPartRevOps = null;
		this.edvEcoRevOps = null;
		this.txtPartNum.Leave -= new System.EventHandler(this.txtPartNum_Leave);
		this.btnSearch.Click -= new System.EventHandler(this.btnSearch_Click);
		this.btnEditCheckOut.Click -= new System.EventHandler(this.btnEditCheckOut_Click);
		this.btnEditCheckIn.Click -= new System.EventHandler(this.btnEditCheckIn_Click);



		this.PartRevOps_Row.EpiRowChanged -= new EpiRowChanged(this.PartRevOps_AfterRowChange);
		// End Wizard Added Object Disposal

		// Begin Custom Code Disposal

		// End Custom Code Disposal
	}

	private void RefreshMe()
	{			
		MainController.AppControlPanel.HandleToolClick("RefreshTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["RefreshTool"], null));
	}

	private void ClearMe()
	{			
		MainController.AppControlPanel.HandleToolClick("ClearTool", new 
		Infragistics.Win.UltraWinToolbars.ToolClickEventArgs(MainController.MainToolManager.Tools["ClearTool"], null));
	}

	public void SetupECODV()
 // Creates the view into EcoRev (BAQ = getPartRevOpECO)
	{
		dtPartRevOps = new DataTable(); //instantiate DT
		
		var colMyPart = new DataColumn("Part"); // inst column
		colMyPart.ExtendedProperties["Like"]="Part.PartNum";	//add like for right click open with
		dtPartRevOps.Columns.Add(colMyPart); // add custom column to DT (repeat for all columns)
		
		var colMyRev = new DataColumn("Rev"); // inst column
		dtPartRevOps.Columns.Add(colMyRev); // add custom column to DT (repeat for all columns)
		
		dtPartRevOps.Columns.Add(new DataColumn("SysRowId",typeof(Guid))); // add guid column to DT (required)
		
		var dr = dtPartRevOps.NewRow(); //inst a new row
		dr["SysRowId"] = Guid.NewGuid(); // just set the guid for the new row
		dtPartRevOps.Rows.Add(dr); // add the row to the DT to enable fields in the table

		dvPartRevOps = new EpiDataView(); //inst the EDV
		dvPartRevOps.dataView = dtPartRevOps.DefaultView; // set the EDV to the default view of the DT created above (default view is unfiltered view of entire DT)
		oTrans.Add("OpsList",dvPartRevOps); // adds the EDV to the binding list

		bdvEco = new BAQDataView("getPartRevOpECO"); //inst the BDV
		oTrans.Add("EcoRevOps",bdvEco); //add the BDV to the binding list (this is an unfiltered BDV. Filter the BDV with Pub/Sub)

		var fromPubPart= "OpsList.Part"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubPart,"FromPubPart"); //publish the value to otrans
		var fromPub = oTrans.GetPublisher(fromPubPart); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvEco.SubscribeToPublisher(fromPub.PublishName,"ECORev_PartNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.

		var fromPubRev= "OpsList.Rev"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubRev,"FromPubRev"); //publish the value to otrans
		var fromPub2 = oTrans.GetPublisher(fromPubRev); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvEco.SubscribeToPublisher(fromPub2.PublishName,"ECORev_RevisionNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
	}
	
	public void SetupPartDV()
 // creates the view into PartRev (BAQ = EditAnyOp)
	{
		dtPartRevOps = new DataTable(); //instantiate DT
		
		var colMyPart = new DataColumn("Part"); // inst column
		colMyPart.ExtendedProperties["Like"]="Part.PartNum";	//add like for right click open with
		dtPartRevOps.Columns.Add(colMyPart); // add custom column to DT (repeat for all columns)
		
		var colMyRev = new DataColumn("Rev"); // inst column
		dtPartRevOps.Columns.Add(colMyRev); // add custom column to DT (repeat for all columns)
		
		dtPartRevOps.Columns.Add(new DataColumn("SysRowId",typeof(Guid))); // add guid column to DT (required)
		
		var dr = dtPartRevOps.NewRow(); //inst a new row
		dr["SysRowId"] = Guid.NewGuid(); // just set the guid for the new row
		dtPartRevOps.Rows.Add(dr); // add the row to the DT to enable fields in the table

		dvPartRevOps = new EpiDataView(); //inst the EDV
		dvPartRevOps.dataView = dtPartRevOps.DefaultView; // set the EDV to the default view of the DT created above (default view is unfiltered view of entire DT)
		oTrans.Add("OpsList1",dvPartRevOps); // adds the EDV to the binding list

		bdvPart = new BAQDataView("EditAnyOp"); //inst the BDV
		oTrans.Add("PartRevOps",bdvPart); //add the BDV to the binding list (this is an unfiltered BDV. Filter the BDV with Pub/Sub)

		var fromPubPart1= "OpsList1.Part"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubPart1,"FromPubPart1"); //publish the value to otrans
		var fromPub1a = oTrans.GetPublisher(fromPubPart1); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvPart.SubscribeToPublisher(fromPub1a.PublishName,"PartRev_PartNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
		
		var fromPubRev1= "OpsList1.Rev"; //whenever the listed field changes publish the new value
		oTrans.PublishColumnChange(fromPubRev1,"FromPubRev1"); //publish the value to otrans
		var fromPub2a = oTrans.GetPublisher(fromPubRev1); //this pulisher 'fromPub' gets the notification when above field changes.
		bdvPart.SubscribeToPublisher(fromPub2a.PublishName,"PartRev_RevisionNum"); // subscribe BDV to fromPub created above. filer by listed field based on publisher.
	}

	private void FilterBAQDataView(BAQDataView iBaqView, string iWhereClause)
	{
	    iBaqView.AdditionalFilter = iWhereClause;
	    iBaqView.dataView.RowFilter = iWhereClause;
	    iBaqView.Notify(new EpiNotifyArgs(oTrans, 0, EpiTransaction.NotifyType.Initialize));		
		//not sure if code below is needed...
		MethodInfo mi = iBaqView.GetType().GetMethod("InvokeExecute", BindingFlags.Instance | BindingFlags.NonPublic);
		mi.Invoke(iBaqView, new object[]{ true });
	}

	private void CheckForCheckedOut()
	{
		FilterBAQDataView(bdvEco,  "ECORev_PartNum = '"  + txtPartNum.Text + "' AND ECORev_RevisionNum = '" +  cmbRevNum.Text + "'");
		FilterBAQDataView(bdvPart, "PartRev_PartNum = '" + txtPartNum.Text + "' AND PartRev_RevisionNum = '" + cmbRevNum.Text + "'");
		if (bdvEco.dataView.Count > 0)
		{ //Show ECORev
			MessageBox.Show("Checked Out!");
			epiGridEcoRev.EpiBinding = "EcoRevOps";
			epiGridEcoRev.Text = "These Operations Are Checked Out!";
			epiGridEcoRev.Refresh();
			epiGridPartRev.Hide();
			epiGridEcoRev.Show();
			txtPartNum.EpiBinding = "OpsList.Part";
			cmbRevNum.EpiBinding = "OpsList.Rev";
		}
		else //Show PartRev
		{
			MessageBox.Show("Not Checked Out!");
			epiGridPartRev.EpiBinding = "PartRevOps";
			epiGridPartRev.Text = "These Operations Are Not Checked Out!";
			epiGridPartRev.Refresh();
			epiGridEcoRev.Hide();
			epiGridPartRev.Show();
			txtPartNum.EpiBinding = "OpsList1.Part";
			cmbRevNum.EpiBinding = "OpsList1.Rev";
		}
	}
	
	private void getRevs()
	{
		cmbpartrev = (Ice.Lib.Framework.BAQCombo)csm.GetNativeControlReference("67f0a748-4944-468b-96b0-cce76dfb5588");
		DynamicQueryAdapter dqa = new DynamicQueryAdapter(oTrans);
		dqa.BOConnect();		
		QueryExecutionDataSet qeds = dqa.GetQueryExecutionParametersByID("getPartRev");
		qeds.ExecutionParameter.Clear();
		qeds.ExecutionParameter.AddExecutionParameterRow("part", txtPartNum.Text, "nvarchar", false, Guid.NewGuid(), "A");
		dqa.ExecuteByID("getPartRev", qeds);
		if (dqa.QueryResults.Tables["Results"].Rows.Count > 0)
		{
			cmbpartrev.DataSource = dqa.QueryResults.Tables["Results"];
			cmbpartrev.DisplayMember = "PartRev_RevisionNum";
			cmbpartrev.ValueMember = "PartRev_RevisionNum";
			//oTrans.NotifyAll();
		}
	}
	
	private void CleanFields()
	{
		oTrans.PushStatusText("Clearing User Fields...", false);
		MyComment.Text = "";
		MyReason.Text = "";
		MyResourceID.Text="";
		MyRGID.Text="";
		MyOp.Text="";
		MyQtyPerParent.Value=null;
		MySetHours.Value=null;
		MyProdTime.Value=null;
		oTrans.PushStatusText("Done!", false);
	}

	private void txtPartNum_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		if(txtPartNum.Text != "") 
		{
		getRevs();
		}
	}

	private void cmbRevNum_Leave(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		//MessageBox.Show("Updating grid!");
		if (txtPartNum.Text != "")
		{
			if (cmbRevNum.Text != "")
			{
				CheckForCheckedOut();
			}
		}
	}

	private void btnSearch_Click(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
	}

	private void btnEditCheckOut_Click(object sender, System.EventArgs args)
	{
		RunCode(true);
	}

	private void btnEditCheckIn_Click(object sender, System.EventArgs args)
	{
		RunCode(false);
	}
	
	private void RunCode(bool checkOut)
	{
		oTrans.PushStatusText("Validating User Data...", false);

		//Validate User Entry Fields
		if (txtPartNum.Text == "") {MessageBox.Show("You must enter a valid part number to edit."); return;} 
		if (checkOut == true)
		{ //Skip Check in, so ignore reason box.
			if (MyComment.Text == "") {MessageBox.Show("Comment Missing!"); return;}
			if (MyResourceID.Text == "") {MessageBox.Show("Resource ID Missing!"); return;}
			if (System.Convert.ToDecimal(MyQtyPerParent.Value)==0) {MessageBox.Show("Quantity per Parent Missing!"); return;}
		}
		else
		{ //Dont skip check in, so watch the reason box.
			if (MyComment.Text == "") {MessageBox.Show("Comment Missing!"); return;}
			if (MyReason.Text == "") {MessageBox.Show("Reason Missing!"); return;}
			if (MyResourceID.Text == "") {MessageBox.Show("Resource ID Missing!"); return;}
			if (System.Convert.ToDecimal(MyQtyPerParent.Value) == 0) {MessageBox.Show("Quantity per Parent Missing!"); return;}
		}
		oTrans.PushStatusText("Pushing User Data to CallContextBpmData...", false);
		EpiDataView edvCallContextBpmData = ((EpiDataView)(this.oTrans.EpiDataViews["CallContextBpmData"]));
		System.Data.DataRow edvCallContextBpmDataRow = edvCallContextBpmData.CurrentDataRow;
		edvCallContextBpmDataRow["Character01"] = txtPartNum.Text;
		edvCallContextBpmDataRow["Character02"] = cmbRevNum.Text;
		edvCallContextBpmDataRow["Character03"] = MyComment.Text;
		edvCallContextBpmDataRow["Character04"] = MyReason.Text;
		EpiDataView edv = (EpiDataView)this.oTrans.EpiDataViews["CallContextClientData"];
		string myUserString = edv.dataView[0]["CurrentUserId"].ToString();
		edvCallContextBpmDataRow["Character05"] = myUserString;
		edvCallContextBpmDataRow["Character06"] = MyResourceID.Value.ToString();
		edvCallContextBpmDataRow["Number01"] = MyOp.Value;		
		edvCallContextBpmDataRow["Number02"] = MyQtyPerParent.Value;	
		edvCallContextBpmDataRow["Number03"] = MySetHours.Value;
		edvCallContextBpmDataRow["Number04"] = MyProdTime.Value;	
		edvCallContextBpmDataRow["Checkbox01"] = checkOut;
		
		// Run custom code in BPM
		oTrans.PushStatusText("Running Custom Action...", false);
		var edvV = oTrans.Factory("PartRevOps");
		BAQRunCustomAction(edvV, "EditOp");
		oTrans.PushStatusText("Done!", false);
	} 
	
	private void BAQRunCustomAction(EpiDataView iEdv, string iActionID)
	{
	    BAQDataView BAQView = (BAQDataView)iEdv;
	    Assembly assembly = Assembly.LoadFrom("Ice.Lib.EpiClientLib.dll");
	    Type t = assembly.GetType("Ice.Lib.Framework.BAQUpdater");
	    BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
	    MethodInfo mi = t.GetMethod("BAQRunCustomAction", bf);
	    object[] param = new object[] { BAQView, iActionID};
	    mi.Invoke("Ice.Lib.Framework.BAQUpdater", param);
	}

	private void PartRevOps_AfterRowChange(EpiRowChangedArgs args)
	{
		// ** Argument Properties and Uses **
		// args.CurrentView.dataView[args.CurrentRow]["FieldName"]
		// args.LastRow, args.CurrentRow, args.CurrentView
		// Add Event Handler Code
	}
}

Thanks!
Nate

I am trying to pull row values from one of the ultragrids and put the values into text fields on the dashboard. The code below worked to pull values from my native grid. This code was held inside an “After Row Change” event for my native grid.
But now I have two custom grids, and I am ignoring my native grid. I can’t figure out how to use AfterRowChange on my custom grids, so I am trying to put this code in a button instead.

My problem is the syntax for pulling the value from the selected row in my custom grid. Honestly, I would much rather get the AfterRowChange event working. That way the syntax doesn’t need to change. But I am open to new ideas.
Thanks!
Nate

private void btnSearch_Click(object sender, System.EventArgs args)
{
MyResourceID.Value = args.CurrentView.dataView[args.CurrentRow]["PartOpDtl_ResourceGrpID"].ToString();
MyRGID.Value = args.CurrentView.dataView[args.CurrentRow]["PartOpDtl_ResourceGrpID"].ToString();
MyComment.Text = args.CurrentView.dataView[args.CurrentRow]["PartOpr_CommentText"].ToString();
}

Just bind the TextFields to the BAQ Binding… Instead of setting the value?

1 Like

Setting the EpiBinding makes my fields read-only. I want to pull the values from either table into the fields so that I can edit the values and then resubmit them. Can EpiBound fields be editable?

Once I change the EpiBindings for a field, is there a way to update them so that the binding displays the value from the related view?

I set all my EpiBindings for text fields to null in the customizer. Then, via code, I set the epibindings based on whether or not there are any part/revs checked out to the user. The epibindings do get set correctly. I can tell by entering customization mode after choosing a part/rev. By doing this I can see that the text field epibindings do get updated by the code, but the fields remain blank, instead of updating as I click on each operation in the bound view (an ultragrid).

private void SetFieldBindings(bool checkOut)
	{
		oTrans.PushStatusText("Pulling Part/Rev Op Details...", false);

		if (checkOut == false)
		{
		txtPartNum.EpiBinding = "PartRevOps.PartRev_PartNum";
		cmbRevNum.EpiBinding = "PartRevOps.PartRev_RevisionNum";		
		MyComment.EpiBinding = "PartRevOps.PartOpr_CommentText";
		string myCom = MyComment.Text.Replace("\x0A",Environment.NewLine);				
		MyComment.Text = myCom;
		MyResourceID.EpiBinding="PartRevOps.PartOpDtl_ResourceGrpID";
		MyRGID.EpiBinding="PartRevOps.PartOpDtl_ResourceGrpID";
		MyOp.EpiBinding="PartRevOps.PartOpr_OprSeq";
		MyQtyPerParent.EpiBinding="PartRevOps.PartOpr_QtyPer";
		MySetHours.EpiBinding="PartRevOps.PartOpr_EstSetHours";
		MyProdTime.EpiBinding="PartRevOps.PartOpr_ProdStandard";
		}
		else
		{
		txtPartNum.EpiBinding = "EcoRevOps.ECORev_PartNum";
		cmbRevNum.EpiBinding = "EcoRevOps.ECORev_RevisionNum";	
		MyComment.EpiBinding = "EcoRevOps.ECOOpr_CommentText";
		string myCom = MyComment.Text.Replace("\x0A",Environment.NewLine);				
		MyComment.Text = myCom;
		MyResourceID.EpiBinding="EcoRevOps.ECOOpDtl_ResourceGrpID";
		MyRGID.EpiBinding="EcoRevOps.ECOOpDtl_ResourceGrpID";
		MyOp.EpiBinding="EcoRevOps.ECOOpr_OprSeq";
		MyQtyPerParent.EpiBinding="EcoRevOps.ECOOpr_QtyPer";
		MySetHours.EpiBinding="EcoRevOps.ECOOpr_EstSetHours";
		MyProdTime.EpiBinding="EcoRevOps.ECOOpr_ProdStandard";		
		}
		//How to update the fields to show the new bindings?
		oTrans.PushStatusText("Done!", false);
	}

Thank you everyone! I think I have a solution. Instead of trying to reuse the textboxes for showing and editing data, I made a hidden set of text boxes for each grid. That way I could epibind the text boxes to each grid. I pull in data from the grid into my user editable controls on a button click event.

I have attached a working version of my dashboard and customization. Feel free to try it out and let me know if you find any issues.
EditAnyOp_NEW.dbd (513.3 KB)
App.EditAnyOp_New.MainController_Customization_custom3_CustomExport.xml (391.2 KB)

Thanks!
Nate