Going from a parent form to a child form without creating a gcnew form - c++-cli

Hello I have a main form (Form1) and a child form (Form5). If I click a button for the first time I want it to open a new form. However if it is being clicked for the second time I want it to open the form I opened the first time, holding that forms data I will have filled in (textboxes etc). This is what I have:
.cpp file:
System::Void Form1::button5_Click(System::Object^ sender, System::EventArgs^ e){
formclick++;
if (formclick == 1)
{
Form5 ^dos1 = gcnew Form5(this, MyArray, MyArray1);
dos1->Show();
}
if (formclick==2)
{
otherform->Show();
}
Form1.h file:
> Form1(System::Windows::Forms::Form ^ Form5)
> {
>
>
> otherform = Form5;
> InitializeComponent();
> } public: System::Windows::Forms::Form ^ otherform;
However I get the error:
An unhandled exception of type 'System.NullReferenceException' occurred in System.Windows.Forms.dll
Additional information: Object reference not set to an instance of an object.
TIA

You are storing the newly created form in the local scope of the button5_click function (in the dos1 variable) and that means it is free to be removed from memory when the function exists.
The code excerpts you've given is a little messy, but it could be enough for you to change the click funtion to the following:
System::Void Form1::button5_Click(System::Object^ sender, System::EventArgs^ e){
if (!otherForm)
otherForm = gcnew Form5(this, MyArray, MyArray1);
else
otherform->Show();
}
Code not tested, but the principal thing is that you need to store the newly created form in a class member, and not only locally to the click funtion!
Regards
Even

Related

Outlook VSTO Addin - NormalEmail.dotm not saved

I'm trying to register a handler for the WindowSelectionChanged event. It works, but when quitting Outlook, it will discard any changes to NormalEmail.dotm file.
For example, any changes to the Quick Part Gallery (Insert->Text->QuickParts) will only be visible during the current session; closing Outlook and starting it again will show the previous list of elements, even if they were deleted, or new ones were added).
Deleting the file :
C:\Users[USER]\AppData\Roaming\Microsoft\Templates\ NormalEmail.dotm
should prompt Outlook to create a new one, but this won't happen when the Addin is enabled.
This can be reproduced by registering even an empty method to the WindowSelectionChange event:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.Inspectors.NewInspector += new Outlook.InspectorsEvents_NewInspectorEventHandler(RegisterChangeHandler);
}
void RegisterChangeHandler(Outlook.Inspector inspector)
{
Microsoft.Office.Interop.Word.Application app = Application.ActiveExplorer().ActiveInlineResponseWordEditor?.Application;
--> app.WindowSelectionChange += WinSelectionChange; <-- this line causes the bug
}
private void WinSelectionChange(Selection Sel)
{
/* nothing */
}
...
}
This causes no exceptions; the result is the same when putting try/catch blocks in place, or when the callback is unregistered in the Application.Quit event.
Question: How can Outlook be made to commit the NormalEmail.dotm file, while also being able to register a callback for WindowSelectionChange event ?
(the project type is "2013 and 2016 VSTO Addin")

(C++ / CLI) Set contents of textbox to content of a .txt

I am looking to set the contents of a textbox to that of a .txt file,
however I cannot get it to work. I have a button which would "refresh" the
content of the textbox to that of the .txt file, here is the code I am using:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
std::ifstream dat1("DataStore.txt");
String^ textHolder;
if (dat1.is_open())
{
while ( getline(dat1, line) )
{
textHolder += line.c_str;
}
textBox1->Text = textHolder;
dat1.close();
}
else textBox1->Text = "Unable to open file";
}
I get these 2 errors when compiling the program:
error C3867: 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str': function call missing argument list; use '&std::basic_string<char,std::char_traits<char>,std::allocator<char>>::c_str' to create a pointer to member
error C2297: '+=' : illegal, right operand has type 'const char *(__thiscall std::basic_string<char,std::char_traits<char>,std::allocator<char>>::* )(void) throw() const'
How do I make this work?
NOTE: I am trying to display the whole .txt file's contents in the textbox
If you are going to use C++/CLI you may as well take advantage of .net. You can use the File class to read the file for you:
System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
textBox1->Text = System::IO::File::ReadAllText("DataStore.txt");
}
You'll need to hope that the process working directory contains that file. In a GUI app you are better served by specifying full paths to files, since the working directory is typically ill-defined.
If you are trying to learn C++, then perhaps a .net C++/CLI WinForms application is not the place to start.
You forgot to end method c_str, change it to c_str()

NavigationService.Navigate throws an exception and invokes Application_UnhandledException in WP8

I am developing a simple WP8 application using VS 2013. I have a MainPage.xaml and added a new page called Page1.xaml. I have a list of options on screen when a user clicks on "new item" I want to open a new page to add new item (Page1.xaml for instance).
On the list selection changed event I have written the following code:
private void OptionssList_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selection = (MenuItem) e.AddedItems[0];
switch (selection.Id)
{
case 0:
break;
case 1:
break;
case 2:
this.NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.Relative));
break;
case 3:
break;
default:
break;
}
}
When I try to debug the application, I notice that the constructor of Page1.xaml is invoked if I had an OnNavigatedTo event handler it is also been invoked however after all this an Unhandled exception is thrown. There is no code that I can see when the exception is thrown however it invokes the Application_UnhandledException event handler.
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
// An unhandled exception has occurred; break into the debugger
Debugger.Break();
}
}
The exception details is as shown below:
System.NullReferenceException was unhandled
Message: An unhandled exception of type 'System.NullReferenceException' occurred in System.Windows.ni.dll
Additional information: Object reference not set to an instance of an object.
I would like to know if I am missing something. I referred to the sample it also shows similar way to Navigate, did not notice any things fancy.
i know this may be a very stupid question, your code looks fine to me, is your page not maybe in another folder? I always put my pages in a folder called UI, so my code will look something like this:
/folder1/folder2/pagename
this.NavigationService.Navigate(new Uri("/UI/Generics/Page.xaml", UriKind.Relative));
Just make sure of that, cause that usually get me.

Get information from different hidden Form C++/clr

I have a Windows Form application I am creating in C++/CLR Visual Studio 2012.
The goal is to have the user input values into the form named Home Page. Then once all the info is filled in they click a button and the Home Page form is hidden and then second form called Setup Info is shown.
The part I need help with is the info from Home Page needs to be accessible in Setup Info. To get an idea of how my files are setup this is the youtube video I followed to create my C++ Windows Form Application Click Here.
In my HomePage.h
// Button that will hide the Home Page Form and then show the SetupInfo Form.
private: System::Void Start_Click(System::Object^ sender, System::EventArgs^ e) {
this->Hide();
SetupInfo^ SetupInfo = gcnew ExcelToPPT::SeuUpInfo();
SetupInfo->Show();
}
In my Setup Info.H
// When Setup Info is loaded button1 will have the text of textbox1 from Home Page Form.
private: System::Void SetupInfo_Load(System::Object^ sender, System::EventArgs^ e) {
button1->Text = HomePage->Textbox1->Text;
}
This is the general idea but it doesn't work. How do I get this to work?
Let me know if you need any more information.
[EDIT]
I am able to do this through extern global variables, but is there another way to directly access the text text boxes?
Also wen I exit out of my Setup Information it doesn't seem to kill my program how do I solve this problem?
The simplest thing would probably be to just pass your Home Page form to the new SetUpInfo form.
private: System::Void Start_Click(System::Object^ sender, System::EventArgs^ e) {
this->Hide();
SetUpInfo^ setUpInfo = gcnew ExcelToPPT::SetUpInfo(this);
setUpInfo->Show(); ^^^^
}
In SetUpInfo.h:
public ref class SetUpInfo : Form
{
private:
HomePage^ homePage;
public:
SetUpInfo(HomePage^ homePage);
};
In SetUpInfo.cpp:
SetUpInfo::SetUpInfo(HomePage^ homePage)
{
this->homePage = homePage;
}
void SetUpInfo::SetUpInfo_Load(System::Object^ sender, System::EventArgs^ e)
{
button1->Text = this->homePage->Textbox1->Text;
}

Unsubscribe from IObservableElementEnumerable.EnumerableChanged doesn't work?

Parts of our UI uses IObservableElementEnumerable.EnumerableChanged in order to update if the user e.g. deletes a domain object from a folder.
When the UI is disposed, we unsubscribe from the event... or so we thought. It turns out that the unsubscribe doesn't have any effect, and our event handler is still called. This caused a number of odd bugs, but also leads to memory leaks.
The only time unsubscription works, is if we store the IObservableElementEnumerable reference instead of calling IObservableElementEnumerableFactory.GetEnumerable(obj) again. But this, in turn, is likely to keep a live reference to the folder object, which will break if the folder itself is deleted by the user.
This is particularly puzzling as the GetEnumerable() documentation clearly states: "It is expected that subsequent calls with the same domain object will yield the same instance of IObservableElementEnumerable." Is this not to be interpreted as a guarantee?
Should there be any reason for unsubscription not working?
The following code replicates the issue on Petrel 2011 (add to a simple plugin with a menu extension, or get the full solution here (DropBox)):
using System;
using System.Linq;
using System.Windows.Forms;
using Slb.Ocean.Core;
using Slb.Ocean.Petrel;
using Slb.Ocean.Petrel.Basics;
using Slb.Ocean.Petrel.UI;
namespace ObservableElementEnumerable
{
public class OEEForm : Form
{
private Droid _droid;
private bool _disposed;
public OEEForm()
{
IInput input = PetrelProject.Inputs;
IIdentifiable selected = input.GetSelected<object>().FirstOrDefault() as IIdentifiable;
if (selected == null)
{
PetrelLogger.InfoOutputWindow("Select a folder first");
return;
}
_droid = selected.Droid;
GetEnumerable().EnumerableChanged += enumerable_EnumerableChanged;
PetrelLogger.InfoOutputWindow("Enumerable subscribed");
}
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
if (disposing && !_disposed)
{
GetEnumerable().EnumerableChanged -= enumerable_EnumerableChanged;
PetrelLogger.InfoOutputWindow("Enumerable unsubscribed (?)");
_droid = null;
_disposed = true;
}
}
IObservableElementEnumerable GetEnumerable()
{
if (_disposed)
throw new ObjectDisposedException("OEEForm");
object obj = DataManager.Resolve(_droid);
IObservableElementEnumerableFactory factory = CoreSystem.GetService<IObservableElementEnumerableFactory>(obj);
IObservableElementEnumerable enumerable = factory.GetEnumerable(obj);
return enumerable;
}
void enumerable_EnumerableChanged(object sender, ElementEnumerableChangeEventArgs e)
{
PetrelLogger.InfoOutputWindow("Enumerable changed");
if (_disposed)
PetrelLogger.InfoOutputWindow("... but I am disposed and unsubscribed!");
}
}
public static class Menu1
{
public static void OEEBegin1_ToolClick(object sender, System.EventArgs e)
{
OEEForm f = new OEEForm();
f.Show();
}
}
}
To replicate:
Run Petrel with the plugin
Load a project with a folder with objects
Select the folder
Activate the plugin menu item
With the popup open, delete an object in the folder
Close the Form popping up
Delete an object in the folder
The message log should clearly show that the event handler is still called after the form is disposed.
You already keep a reference to the underlying enumerable by connecting the event. Events are references as well. Just keep a reference to the enumerable and unsubscribe from the same instance as the one you subscribe to.
To deal with the issue of objects that are deleted by the user you need to listen to the delete event.