Vc++, Use function from form1 in form2, by calling - winforms

I have been looking for help everywhere. So far havent found the help i need.
I hope you guys can guide or help me =)
I have a Form1, on form1 i have included in Form1.h the second forms file: Form2.h
So now i have created, which runs when a button is pressen:
| Form1.h |
Form2^ frmProSog = gcnew Form2();
frmProSog->ShowDialog();
Now Form2 is open and i use it to search for a string in a datagrid. When i have selected the result, I will click on a button in Form2 which I want to call a function in Form1 which will add the data in another datagrid which is in Form1.
I have tried to include Form1.h in Form2 but i get an error: cannot be called with the given argument list argument types are: (System::Object ^)
I hope that someone out there is able to help me. Tried many of the following suggestions on stackoverflow which reminds of this question but no luck.

(David Yaw's comment is correct, I write the following on the basis that the OP might need more explicit instructions. This answer is just pointing out usual C++ techniques, not something particularly specific to CLI/C++ or WinForms.)
It seems to me from your description that the body of your button-press event functions must have been in the respective header files. Furthermore, that #include "Form1.h" is in Form2.h, and vice-versa: this causing the circular dependency and associated pain.
The simple fix is to implement the event-handling methods in the Form1.cpp and Form2.cpp source files instead. Once the form designer creates the empty method...
public ref class Form 1 : System::Windows::Forms::Form
{
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
}
}
... then remove the implementation from the header.
public ref class Form 1 : System::Windows::Forms::Form
{
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) ;
}
Copy/Paste into the cpp file, and add the handler body
System::Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e) {
Form2^ frmProSog = gcnew Form2();
frmProSog->ShowDialog();
}
Remove the respective #include from the .h and put into the .cpp instead.
(If there is a member of Form1 which is a Form2^, forward declare Form2 in Form1.h)
The above will work because, on the basis of your question, there is no visual representation (i.e., in the form designer) of Form1 in Form2, or Form2 in Form1. In this case, you can have as much circular dependency as you like between forms/controls, as long as you forward declare in the *.h, and only "use" (access members, etc) circularly-dependent classes in source files. You can happily take handles (^) to Form2 in Form1.h with forward declaration, including Form2^ as member functions and method signatures.

Related

How to override toolstrip renderer?

I am new to visual studio and c++, I have created a new CLR Empty Project and have started adding some controls. I notice this strange artefact on the right edge of the toolstrip and would like to remove it.
This question Why am I getting a vertical line on toolstrip? provides a solution in c# but I am having trouble trying to make it work in visual c++.
First i made new .cpp file called CustomerRenderer.cpp and the code looks like this:
using namespace System::Windows::Forms;
private ref class CustomRenderer : ToolStripRenderer
{
protected:
virtual void OnRenderToolStripBorder(ToolStripRenderEventArgs^ e) override
{
ToolStripRenderer::OnRenderToolStripBorder(e);
}
};
Then on my forms load I put this:
private: System::Void MainForm_Load(System::Object^ sender, System::EventArgs^ e) {
this->toolStrip1->Renderer = gcnew CustomRenderer();
}
And this just makes the toolstrip disappear completely rather than fix the edge artefact. I like the style of the gradient toolstrip so would rather not change to the system renderer.
How can I override the toolstrip renderer in a visual c++ project and remove the edge border artefact?
Thanks
Ok I solved by changing:
private ref class CustomRenderer : ToolStripRenderer
to
private ref class CustomRenderer : ToolStripProfessionalRenderer

WinForm text box: MenuStrip keyboard shortcuts overriding OS-level copy/paste

Update: I've figured out the source of the issue, now trying to figure out the best fix
I've got a Form with a customized MenuStrip, with all sorts of bells and whistles. Of note here, is that many of my MenuStrip items have keyboard shortcuts - namely ones for Cut/Copy/Paste.
It appears that the presence of this MenuStrip is overriding (and therefore cancelling) the default Cut/Copy/Paste keyboard shortcut behaviors for my text boxes (and other controls).
All of them.
.
I can't really say I have a reason for the MenuStrip Cut/Copy/Paste options, besides the fact that I would expect to see them there. That's how Office type programs operate, and it's something the user (myself included) would expect.
I could remove the Cut/Copy/Paste options from the MenuStrip, but that would be admitting defeat! So how do I keep my overly engineered MenuStrip from forcing me to implement custom code for EVERY control that's Cut/Copy/Paste friendly?
.
** Original Post: **I've got a TextBox control in a toolbar which is to be used throughout my program. Imagine my surprise when native OS-level Copy/Paste events were not supported by default.
Sure, I could code something manually, but when I right-click on the control, Cut/Copy/Paste are already built in. How can I leverage this existing functionality?
I figure adding a KeyDown event with Ctrl+C, P, and X would be about the maximum I should have to code. For those events I just call a built-in method or something. That, or find a setting that enables native cut/copy/paste.
What am I overlooking/missing?
Testing it out native copy and paste does work on a TextBox control unless you are overridding the ContextMenu or ContextMenuStrip, in that case you will need to use the ClipBoard Class to implement it yourself.
In looking at it further this MSDN Forum article discusses sending the Commands to the Native Textbox Control using the SendMessage Method. This is implemented in a Custom TextBox which sounds like what you are doing.
Small excerpt see article for further implementation:
protected void itemCut_Click(object sender, EventArgs e)
{
SendMessage(this.Handle, TextBoxMessages.WM_CUT, 0, 0);
}
public static class TextBoxMessages
{
public const int EM_UNDO = 0x00C7;
public const int WM_CUT = 0x0300;
public const int WM_COPY = 0x0301;
public const int WM_PASTE = 0x0302;
}
Easy Solution: Use the SendKeys.Send() call within the Click event.
SendKeys.Send("^X");
I'm doing something a little more complicated, so here's the details:
I'm making several Forms, which all share some custom controls: MenuStrip, StatusStrip, and a few other custom controls. I've decided to have the Forms all inherit from the same base class, to allow common implementation of lots of stuff.
public partial class CommonFormBase : Form
{
private void Initialize()
{
//Bind click event for custom MenuStrip to events in the local Form
CommonMenuStrip.Edit_Cut.Click += new EventHandler(Edit_Cut_Click);
CommonMenuStrip.Edit_Copy.Click += new EventHandler(Edit_Copy_Click);
CommonMenuStrip.Edit_Paste.Click += new EventHandler(Edit_Paste_Click);
}
//Implement Click events for the MenuStrip by calling local methods
internal void Edit_Cut_Click(object sender, EventArgs e) { Cut(); }
internal void Edit_Copy_Click(object sender, EventArgs e) { Copy(); }
internal void Edit_Paste_Click(object sender, EventArgs e) { Paste(); }
//Generic implementation of common commands for the CommonFormBase
public virtual void Cut() { SendKeys.Send("^X"); }
public virtual void Copy() { SendKeys.Send("^C"); }
public virtual void Paste() { SendKeys.Send("^V"); }
}
I implemented the MenuStrip's click event at the Form level (not the MenuStrip level), but in that event I only call a generic method, which does all the code. In this example it's overkill, but I have other MenuStrip commands that will change in functionality for different child Forms, so I figured having them all work the same would be easier.
Anyway, this works almost perfectly! It seems to push the shortcut-key-activated MenuStrip_Click event to the underlying control (or maybe the Form?), which then implements default shortcut key events.
The only thing it does wrong is it only triggers ONCE when you do Ctrl + V + V + V... or hold Ctrl+V. Still, that's just a matter of the trigger not recognizing multiple events, not an issue with the solution itself.

load event not fired in inherited user control loaded from another assembly (Winforms)

I have an application with plugin-like structure.
all application forms inherit from a base UserControl :
public class BaseUserControl : UserControl
{
// some common properties and methods
//
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
}
and are compiled in different assemblies.
When I want to show a form, it goes through this sequence:
assembly = Assembly.LoadFile(assemblypath);
.
.
frm = (BaseUserControl)assembly.CreateInstance(frmname);
.
.
SomeContainer.Controls.Add(frm);
MainScreen.Controls.Add(SomeContainer);
Common structure of these forms is :
public class TestForm : BaseUserControl {
public TestForm(){InitializeComponent();}
private void InitializeComponent(){
.
.
this.Load += new System.EventHandler(this.TestForm_Load);
.
}
private void TestForm_Load(object sender, EventArgs e){}
}
The problem is that the Load event of these forms does not get fired.
Another behavior, I don't understand how, when setting a break point at the OnLoad in the base class, the call stack shows that is called from within the InitializeComponent.
Any ideas on how to solve this?
You are hopelessly mixing up the terms Form and UserControl, making it very hard to give a good answer. They are very different beasts, you can't turn a UC into a form. It is a client window, not a top-level window. I suspect that has something to do with your problem but the generic diagnostic is that somebody is overriding OnLoad and not calling base.OnLoad().
Yes, OnLoad may be called from code in InitializeComponent(). It isn't very healthy since OnLoad will run before the constructor is finished, but it is supported. This will happen when you touch a property that requires the Handle to be created. The call stack should show you which particular property assignment did this, just double-click the line in the call stack.

Is there a way to bind the results of a public method in xaml.cs to a control in xaml?

Let's take a very simple example:
In my window1.xaml, i have a label
control named 'lblProduct'.
In my window1.xaml.cs, i have a
public method called
CalculateProduct(Int Var1, Int
Var2). CalculateProduct will, as
you may have guessed, calculate the
product of the variables passed in.
I'd like to simply bind the results of 'CalculateProduct' to my label. My actual use case is a little more complicated than this. However, if I could get this up and running not only would I be quite happy, I'd be able to figure out the rest.
I've seen interesting examples using the ObjectDataProvider to bind to a static method of a new class. While this is well and good, I don't feel the need to create a new class when I've already instantiated the one for my window. In addition, there may be other global variables that I'd like to take advantage of in my Window1 class.
Thanks for your time and help,
Abel.
It's quick and dirty but I'd probably just have CalculateProduct set a property with its result and databind to the property.
Yes, there is a way. It's not pretty. You have to add an xmlns:Commands attribute to your window1.xaml tag. I ended up bastardizing some code I found in this Code Project article.
Is the product that you want to display in the label something that's generated on load, or from another control event?
I'm not sure this will help you, but I ran into something similar where I was trying to generate XAML dynamically with XSLT. My solution worked, kind of...well, not really for what I was trying to do. But maybe it will help you.
As I said, you have to declare the xmlns in your page tag, like so:
<Page x:Class="WpfBrowserApplication1.Page1"
blah blah blah
xmlns:Commands="clr-namespace:WpfBrowserApplication1">
Then, define a static class in your application with the same namespace, pretty much the same as the example in the Code Project article, with handlers for a RoutedUICommand:
namespace WpfBrowserApplication1
{
public static class CommandHandlers
{
private static System.Windows.Input.RoutedUICommand _submitCommand;
static CommandHandlers()
{
_submitCommand = new System.Windows.Input.RoutedUICommand("Submit", "SubmitCommand", typeof(CommandHandlers));
}
public static void BindCommandsToPage(System.Windows.Controls.Page caller)
{
caller.CommandBindings.Add(new System.Windows.Input.CommandBinding(SubmitCommand, SubmitContact_Executed, SubmitContact_CanExecute));
}
public static System.Windows.Input.RoutedUICommand SubmitCommand
{
get { return _submitCommand; }
}
public static void SubmitContact_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
...do stuff...
}
public static void SubmitContact_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
{
if (e.Source is System.Windows.Controls.Button)
e.CanExecute = true;
else
e.CanExecute = false;
}
}
}
The nasty part is that, so far as I've found, the only way to map things back to Page1.xaml is to cast the sender object and dig through the UI elements of the Page, similar to how you would dig through the DOM on a web page. I had some success with this, but certainly don't pretend to be an expert.
The last thing you have to do is wire up your control in the Page1.xaml.cs. In the XAML, you do it like so:
<Button Name="btnSubmit" Command="Commands:CommandHandlers.SubmitCommand" etc... />
In the code-behind, like so:
private void Page_Loaded(object sender, RoutedEventArgs e)
{
CommandHandlers.BindCommandsToPage(this);
}
I hope that helps, and good luck.
Why you not just set the label value in your CalculateProduct method before you return from the method. Basically way do you need data binding here? It is one way anyhow, since you are binding to a label.
ObjectDataProvider has an ObjectInstance property that you can assign your Window instance to.
aogan: The idea here is to leverage the flexibility of WPF databinding. I could set the entire UI in the code behind, but MS has developed this binding system and i wanted to easily take advantage of it. Also, this was a simple example for a more complicated problem.
To everyone else involved, i've gone with PITAdev's solution. Thanks for the help.

Custom WPF command pattern example

I've done some WPF programing and one thing I never got was the command pattern. Every example seems to be for built in ones, edit, cut, paste. Anyone have an example or suggestion of best practice for custom commands?
Ah ha! A question I can answer! Firstly, I should mention that I have personally found it easier to define and hook up commands in code rather than in XAML. It allows me to hook up the handlers for the commands a little more flexibly than an all XAML approach does.
You should work out what commands you want to have and what they relate to. In my application, I currently have a class for defining important application commands like so:
public static class CommandBank
{
/// Command definition for Closing a window
public static RoutedUICommand CloseWindow { get; private set; }
/// Static private constructor, sets up all application wide commands.
static CommandBank()
{
CloseWindow = new RoutedUICommand();
CloseWindow.InputGestures.Add(new KeyGesture(Key.F4, ModifierKeys.Alt));
// ...
}
Now, because I wanted to keep the code all together, using a code only approach to Commands lets me put the following methods in the class above:
/// Closes the window provided as a parameter
public static void CloseWindowExecute(object sender, ExecutedRoutedEventArgs e)
{
((Window)e.Parameter).Close();
}
/// Allows a Command to execute if the CommandParameter is not a null value
public static void CanExecuteIfParameterIsNotNull(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = e.Parameter != null;
e.Handled = true;
}
The second method there can even be shared with other Commands without me having to repeat it all over the place.
Once you have defined the commands like this, you can add them to any piece of UI. In the following, once the Window has Loaded, I add command bindings to both the Window and MenuItem and then add an input binding to the Window using a loop to do this for all command bindings. The parameter that is passed is the Window its self so the code above knows what Window to try and close.
public partial class SimpleWindow : Window
{
private void WindowLoaded(object sender, RoutedEventArgs e)
{
// ...
this.CommandBindings.Add(
new CommandBinding(
CommandBank.CloseWindow,
CommandBank.CloseWindowExecute,
CommandBank.CanExecuteIfParameterIsNotNull));
foreach (CommandBinding binding in this.CommandBindings)
{
RoutedCommand command = (RoutedCommand)binding.Command;
if (command.InputGestures.Count > 0)
{
foreach (InputGesture gesture in command.InputGestures)
{
var iBind = new InputBinding(command, gesture);
iBind.CommandParameter = this;
this.InputBindings.Add(iBind);
}
}
}
// menuItemExit is defined in XAML
menuItemExit.Command = CommandBank.CloseWindow;
menuItemExit.CommandParameter = this;
// ...
}
// ....
}
I then also later have event handlers for the WindowClosing and WindowClosed events, I do recommend you make the actual implementation of commands as small and generic as possible. As in this case, I didn't try to put code that tries to stop the Window closing if there is unsaved data, I kept that code firmly inside the WindowClosing event.
Let me know if you have any follow up questions. :)
I blogged about a bunch of resources on WPF Commands along with an example last year at http://blogs.vertigo.com/personal/alanl/Blog/archive/2007/05/31/commands-in-wpf.aspx
Pasting here:
Adam Nathan’s sample chapter on Important New Concepts in WPF: Commands
MSDN article: The Command Pattern In WPF
Keyvan Nayyeri: How to Add Commands to Custom WPF Control
Ian Griffiths: Avalon Input, Commands, and Handlers
Wikipedia: Command Pattern
MSDN Library: Commanding Overview
MSDN Library: CommandBinding Class
MSDN Library: Input and Commands How-to Topics
MSDN Library: EditingCommands Class
MSDN Library: MediaCommands Class
MSDN Library: ApplicationCommands Class
MSDN Library: NavigationCommands Class
MSDN Library: ComponentCommands Class
Also buried in the WPF SDK samples, there's a nice sample on RichTextBox editing which I've extended. You can find it here: RichTextEditor.zip
In the September 2008 edition of the MSDN magazine, Brian Noyes has a excellent article about the RoutedCommand/RoutedEvents!!!
Here is the link:
http://msdn.microsoft.com/en-us/magazine/cc785480.aspx
The thing about XAML is that it is fine for 'simple' programs, but sadly, it doesn't work well when you want to do things like share functions. Say you have several classes and UI's all of which had commands that were never disabled, you'd have to write a 'CanAlwaysExecute' method for each Window or UserControl! That's just not very DRY.
Having read several blogs and through trying several things, I've made the choice to make XAML purely about looks, styles, animation and triggers. All my hooking up of event handlers and commanding is now down in the code-behind. :)
Another gotcha by the way is Input binding, in order for them to be caught, focus must be on the object that contains the Input bindings. For example, to have a short cut you can use at any time (say, F1 to open help), that input binding must be set on the Window object, since that always has focus when your app is Active. Using the code method should make that easier, even when you start using UserControls which might want to add input bindings to their parent Window.

Resources