I have an InfoPath 2013 form I'm working on, and we have the need to switch views based on job category. We can easily determine this based on the job number at the top of the form, but a rule placed in "Form Load" isn't working because the job number field gets populated after the form loads in InfoPath Filler. Essentially I want to show View A if the job number starts with a "1", View B if it starts with a "2", and so on.
This form already has C# code behind it, but I'm banging my head on the desk trying to get this working. In theory, I should be able to use the Change event of the field to switch views, but so far it ignores any code I put in for the "After Change" context of the field.
I'm using the following to switch views:
this.ViewInfos.SwitchView("MyView");
Does anyone have an example of how this should work?
Here is an example about switch view when InfoPath form data changed like Drop-Down List Changed Event for your reference:
public void InternalStartup()
{
EventManager.FormEvents.ContextChanged += new ContextChangedEventHandler(FormEvents_ContextChanged);
EventManager.XmlEvents["/my:DoanhNghieps/my:loaiHinhHoatDong"].Changed += new XmlChangedEventHandler(loaiHinhHoatDong_Changed);
}
public void FormEvents_ContextChanged(object sender, ContextChangedEventArgs e)
{
if (canRedirect)
{
canRedirect = false;
ViewInfos.SwitchView("CN");
}
}
private bool canRedirect = false;
public void loaiHinhHoatDong_Changed(object sender, XmlEventArgs e)
{
// Write your code here to change the main data source.
canRedirect = true;
}
More information: InfoPath: Drop-Down List Changed, Switch View
Related
I'm trying to pass a variable from one form to another form textbox. The 'variable' is a result of a calculation based on the user inputs.
Below is the code for the parent form(RuleInsertForm) where I'm calling the subform(Helpformula) to get the user inputs.
public partial class RuleInsertForm : Form
{
public string helpformulainputs;
}
private void RuleInsertForm_Load(object sender,EventArgs e)
{
if (helpformulainputs=="")
{
textBox_Inputs.Text = "";
}
else
{
textBox_Inputs.Text = helpformulainputs;
}
}
Below is the code for the subform(Helpformula) where i'm passing the result variable(formulainputs) to the parent form(RuleInsertForm).
public partial class HelpFormula : Form
{
public string formulainputs = string.Empty;
private void button_generateformula_Click(objectsender, EventArgs e)
{
using (RuleInsertForm insertform = new RuleInsertForm())
{
insertform.helpformulainputs = formulainputs;
this.Close();
insertform.Show();
}
}
}
Problem:
The values are getting passed to the text box but in the UI its not getting dispalyed.
so far I tried to push data back to parent form and then tried to display the data in the textbox where I failed.(I dont know where it went wrong suggest me if I can resolve the below one)
Now I need an alternative method to this for eg: instead of pushing the data back to parent form i need to make the variable available for all the forms trying to use the subform(formulainputs)
How can I acheive this process ? any suggestions are much appreciated.
The problem seems to be that insertForm.Show() does not block the execution of your button handler. Show opens the insertform as non-modal.
So after insertform is opened, the execution is continued in button_generateformula_Click and when you exit the using block, the insertform is disposed and therefore closed.
To solve this you may call insertForm.ShowDialog() instead.
For different ways of communicating between Forms look here or simply type communicate between forms into the SO search box.
I have the following snippet of code that allows me to pull the properties from an object in my list and assign them to variables in other forms. However, I need to be able to pull the data from my variables in the other form and use those to set the properties of the given object.
My class Account is used to populate my list accounts. On my next form AccountMenu I have a class Variables1 that contains accessible variables that are used throughout the rest of my forms to keep track of the checking balance and saving balance. When logging off from the AccountMenu, I want to be able to pass the values from Variables1 to the account that was initially used.
I know how to pass variables from one form to another, but I'm not really sure how to update the form automatically, without a button, on the original form. Thus, the solution that I see is that I have a button on my AccountMenu form that "logs" the user out, via this.close(); Additionally, I guessed that under that button, I need to have some code that assigns the variables as properties to the object. I'm just not sure how I can access the set properties of the object, since it is dynamically called with the code below.
Can someone help me figure out what I need to do? Below is some of the relevant code so that you can see how I have things set up. I am just not sure how to access "matches" from the other form in order to update that specific object properties. Thank you, anyone, who can help!
//variable that will be used to check textbox1.Text
string stringToCheck;
//array of class Account
List<Account> accounts = new List<Account>();
public MainMenu()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//set value to user's input
stringToCheck = textBox1.Text;
//set a var that only returns a value if the .Name already exists
var matches = accounts.FirstOrDefault(p => p.Name == stringToCheck);
//check through each element of the array
if (matches == null)
{
accounts.Add(new Account(stringToCheck));
textBox1.Text = "";
label3.Visible = true;
}
else if (matches != null)
{
//set variables in another form. not sure if these are working
Variables1.selectedAccount = matches.Name;
//is this calling the CheckBalance of the instance?
Variables1.selectedCheckBalance = matches.CheckBalance;
//same thing?
Variables1.selectedSaveBalance = matches.SaveBalance;
//switch to form
AccountMenu acctMenu = new AccountMenu();
this.Hide();
acctMenu.Show();
}
}
As per my understanding I think what you required is kind of trigger on your parent form that needs to be called from your child application.
If that is what you required than you can go with defining an event on your AccountMenu form. and register this event from your Accounts form.
Than simply raise this event from your AccountMenu subform.
Deletegates and Events are really works like magic :)
Let me show you some code how to do this.
Code required in AccountMenu window:
public delegate void PassDataToAccounts(string result);
public event PassDataToAccounts OnPassDataToAccount;
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
if (OnPassDataToAccount != null)
OnPassDataToAccount("result");
base.OnClosing(e);
}
Code required in Accounts window button1_Click event where the AccountMenu will open:
//set variables in another form. not sure if these are working
Variables1.selectedAccount = matches.Name;
//is this calling the CheckBalance of the instance?
Variables1.selectedCheckBalance = matches.CheckBalance;
//same thing?
Variables1.selectedSaveBalance = matches.SaveBalance;
//switch to form
AccountMenu acctMenu = new AccountMenu();
acctMenu..OnPassDataToAccount += childwindow_OnPassDataToAccount;
this.Hide();
acctMenu.Show();
}
void childwindow_OnPassDataToAccount(string result)
{
if (result == "result")
{
// Processing required on your parent window can be caried out here
//Variables1 can be processed directly here.
}
}
I have a problem with changing my UI strings after the user has changed the language in the option window. To change the UI strings of the main form, I have to restart the program every time, so that changes take effect, but that's annoying. So I tried it with a delegate to call the function, which loads the strings for the main window in the option window after saving the new settings. The function is called in the option window, but it doesn't change the strings of the main window.
Code in the main window
public delegate void CallLoadUIStrings(SupportedLanguages lang);
public CallLoadUIStrings callLoadUIStrings;
public Renamer()
{
callLoadUIStrings = new CallLoadUIStrings(LoadUIStrings);
}
public void LoadUIStrings(SupportedLanguages lang)
{
try
{
switch (lang)
{
#region "DE/JA/FR/ES/NL"
case SupportedLanguages.De:
case SupportedLanguages.Ja:
case SupportedLanguages.Fr:
case SupportedLanguages.Es:
case SupportedLanguages.Nl:
// reads the language file where the ui strings are stored
langHelper.Read(RenamerLangOpener.RenamerMainWindow);
this.mnuFile.Text = langHelper.Files;
this.mnuClose.Text = langHelper.Close;
this.mnuEdit.Text = langHelper.Edit;
this.mnuUndo.Text = langHelper.Undo;
this.mnuCut.Text = langHelper.Cut;
this.mnuCopy.Text = langHelper.Copy;
this.mnuPaste.Text = langHelper.Paste;
this.mnuDelete.Text = langHelper.Delete;
this.mnuSelectAll.Text = langHelper.SelectAll;
#endregion
}
}
catch (Exception ex) { //exception handling }
}
private void mnuOpt_Click(object sender, EventArgs e)
{
Preferences opt = new Preferences(this);
opt.ShowDialog();
}
Code in the option window
internal Renamer instance = null;
public Preferences(Renamer form)
{
instance = form;
}
public void UpdateUI()
{
langHelper.ReadSettingsValues();
instance.BeginInvoke(instance.callLoadUIStrings,new object[] { langHelper.GetLang});
}
Since I've never worked with delegates I don't have a clue where the mistake is.
I've googled so much to find a solution for a similar problem, but I haven't found something that matched my problem.
I assume this is winforms and not WPF question, and that you have one main form that is open from app's Main function. My solution to changing a language is to open this one form in a loop, and continue the loop as long as the form has a property set to some language identifier. If this property is set then I change the language to that value, and go for another loop iteration. I copy all other properties that need be copied form one form to another, with main being the form's position.
If the form is closed without the language ID being set then we break the loop and exit application as usual.
Im currently facing the problem that when i try to set focus on some control (textBox), nothing happens, maybe i just overlooked something.(somewhere i found that focus is "low-level" method and that select() should be used instead, however, it doesnt work as well)
From form Login, i launch new instance of EncryptPSW form
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
EncryptPSW ePSW = new EncryptPSW();
ePSW.setOsLog(false, this);
ePSW.ShowDialog();
}
On Button(which is located on EncryptPSW form ) click event i call fill method
public void fill()
{
if (textBoxPSW.Text.Length == 8)//psw has to be 8 chars long
{
if (save)//determinating whether save or fetch of data should be done
{ login.launchSave(textBoxPSW.Text,this); }
else { login.launchOpen(textBoxPSW.Text,this); }
}
else { MessageBox.Show("The password must contain 8 characters");}
}
Which launches either save or open method from Login (my problem is just with open, since during save i dont need to do anything with Focus)
public void launchOpen(string psw,EncryptPSW ePSW)
{
ePSW.Close();
Encryptor.DecryptFile("loggin.bin", psw, this); //decrypting data and setting textBoxes Text property into the fetched ones
setFocus();
}
After all the work is done, setFocus() should be called in order to set focus and other properties.
public void setFocus()
{
textBoxDatabase.Focus();
textBoxDatabase.SelectionStart = textBoxDatabase.TextLength - 1;
textBoxDatabase.SelectionLength = 0;
}
I tried so many different ways, like:
Calling setFocus() from within EncryptPSW_FormClosed
Calling whole open process after the EncryptPSW is closed (from within EncryptPSW_FormClosed)
and many more, however i dont remember it all.
In the case of Form_Closed the weird thing is, that when i tried to show a message box from there instead of setting focus (just to see where the problem might be), it's showed before the EncryptPSW form is closed.
My only guess about this is that the instance of EncryptPSW is somehow blocking Login form and it's controls
I hoped i described my problem well enough and that it makes at least a bit of sense ;]
Thanks in advance,
Regards,
Releis
Since the textbox is in the login form, and you are opening the EcryptPWS from it as a dialog (child), your login form will not be able to set focus to anything. You will need to set focus after it is closed. You can do this:
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using(EncryptPSW ePSW = new EncryptPSW())
{
ePSW.setOsLog(false, this);
if (ePSW.ShowDialog() == DialogResult.OK)
{
textBoxDatabase.Focus();
}
}
}
public void launchOpen(string psw,EncryptPSW ePSW)
{
ePSW.DialogResult = DialogResult.OK;
ePSW.Close();
Encryptor.DecryptFile("loggin.bin", psw, this); //decrypting data and setting textBoxes Text property into the fetched ones
}
OK this maybe the ugliest thing I saw round this but.
using
public void setFocus()
{
textBoxDatabase.Focus();
textBoxDatabase.SelectionStart = textBoxDatabase.TextLength - 1;
textBoxDatabase.SelectionLength = 0;
}
Change your code at
public void launchOpen(string psw,EncryptPSW ePSW)
{
ePSW.Close();
Encryptor.DecryptFile("loggin.bin", psw, this); //decrypting data and setting textBoxes Text property into the fetched ones
setFocus();
}
to
delegate void settingfocus();
public void launchOpen(string psw,EncryptPSW ePSW)
{
ePSW.Close();
Encryptor.DecryptFile("loggin.bin", psw, this); //decrypting data and setting textBoxes Text property into the fetched ones
settingfocus sf = new settingfocus(setFocus);
this.BeginInvoke(sf);
}
This worked for me
(Sorry for apparently thinking insert "this" before procedure, and change line x to this was legable)
I'm creating a VSTO for my company, and have ran across a interesting issue that I could use some help with. I will try to explain this to the best of my ability. I have the AddIn set up right now for it to create 2 customTaskPanes upon start up via Application.AfterNewPresentation events. And the ability to hide/show these based on user input from togglebuttons on the Ribbon.
Now when I fire up the first PowerPoint 2010 called "Presentation1" everything works great, I can show/hide the TaskPanes and everything inserts the way it should. Now then I open up a second template called "Presentation2"(to help keep things straight here) Everything works great again, I can show/hide the TaskPanes and everything inserts fine. If I go back to "Presentation1" the inserts and everything functions fine, but when I got to hide/show the TaskPanes it hides/shows them on "Presentation2". And if I create a "Presentation3" the same thing will happen but both "Presentation1" and "Presentation2" control "Presentation3" TaskPanes. And if I close the "Presentation2" and "Presentation3" the "Presentation1" buttons do not show/hide anything at all.
Code in the ThisAddIn
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application.AfterNewPresentation += new PowerPoint.EApplication_AfterNewPresentationEventHandler(Application_AfterNewPresentation);
}
private void Application_AfterNewPresentation(PowerPoint.Presentation Pres)
{
PowerPoint.Application app = Pres.Application;
PowerPoint.DocumentWindow docWin = null;
foreach (PowerPoint.DocumentWindow win in Globals.ThisAddIn.Application.Windows)
{
if (win.Presentation.Name == app.ActivePresentation.Name)
{
docWin = win;
}
}
this.myWebForm = new SearchWebForm();
this.myWebFormTaskPane = this.CustomTaskPanes.Add(myWebForm, "Search ",docWin);
this.myWebFormTaskPane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
this.myWebFormTaskPane.Width = 345;
this.myWebFormTaskPane.VisibleChanged += new EventHandler(WebFormTaskPane_VisibleChanged);
}
private void WebFormTaskPane_VisibleChanged(object sender, System.EventArgs e)
{
Globals.Ribbons.Ribbon1.searchButton.Checked = myWebFormTaskPane.Visible;
if (Globals.Ribbons.Ribbon1.searchButton.Checked == true)
{
myWebForm.SearchForm_Navigate();
}
}
And then this is in the ribbon
private void searchButton_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.WebFormTaskPane.Visible = ((RibbonToggleButton)sender).Checked;
}
In PowerPoint 2007, custom task panes are shared across all presentation windows. If you want to have separate task panes assigned to each presentation you need to handle the corresponding events (WindowActivate, PresentationClose, etc.). You would also need to manage a list of all the task panes that you've created so you can show/hide the appropriate one. This is actually a well-known Outlook pattern frequently referred to in VSTO-world as InspectorWrappers - or in your case a DocumentWindowWrapper.
This has been changed for Powerpoint 2010 and now each taskpane is associated with a specific window. See this article.
Your error is that Globals.ThisAddIn.WebFormTaskPane does not necessarily correspond to the current presentations task pane - you need to lookup the proper task pane in your managed list (as mentioned above). When you create a new task pane (AfterNewPresentation), add it to your CustomTaskPane collection and provide a means of retrieving it.
public partial class ThisAddIn
{
private Dictionary<PowerPoint.DocumentWindow, DocumentWindowWrapper> pptWrappersValue =
new Dictionary<PowerPoint.DocumentWindow, DocumentWindowWrapper>();
}