How to interrogate GUI controls in a WPF application? - c#

Still setting my first steps in WPF, this time I'm dealing with this "simple" situation:
dt_Proposal.Rows[0].ItemArray[i] = highest_val + min_val;
This piece of code has been run for every value of i (also for value 2), so I expect to see something on the place of the red rounded rectangle:
However I don't see any value there.
I decided to pauze my application (Visual Studio "Debug" menu, "Break All" menu item), and then I thought of having a look at the controls of my form, but how?
Visual Studio's "Locals" window contains this, which is mentioned being a <Application_Name>.MainWindow, but I can't look deeper.
When adding this to the "Watchlist", this seems not even to be accessible.
So this becomes a very general question: I am working on the GUI of a WPF application, and I would like to see the properties/fields of the controls/GUI components of my main form, and I would like to do this while my application is waiting on any kind of user input (typical "wait state" for a GUI application).
How can I do that?

In WPF you can see Visual Tree (even without pausing the app at all!), you enter this like shown in below picture:
By the way, value hello world was set programatically:
private void Button_Click(object sender, RoutedEventArgs e)
{
txtInfo.Text = "hello world";
}
Once in Visual Tree, you can right click control and show its properties:
And there you can see values of properties set:

Related

How can I add a button to the layout? - C# [duplicate]

This question already has answers here:
How to add buttons dynamically to my form?
(8 answers)
Closed 2 years ago.
I cannot find any methods to add the button to the layout.
I am trying to add the child (button) to the layout, but I can't find any methods to do so.
Source Code:
using System;
using System.Windows.Forms;
namespace WinForms
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Button button = new Button {Height = 100, Width = 100, Text = "Test"};
}
}
}
You open your project in Visual Studio 2019 (not Visual Studio Code, not JetBrains Rider) - free versions for which exist if your context qualifies for the license. If you don't qualify for a free license, you[r workplace] can easily afford a license of some form
You double click Form1 in the solution explorer and then you see something that looks like what the form will look like when you run the program, and you open the controls tool panel and drag a button out of it and drop it onto the form...
But if you want to get into hand-writing the volumes of boring repetitive code to build a UI then you add controls to the Controls collection of other controls, viz:
Form1 f = new Form1();
Button button = new Button {Height = 100, Width = 100, Text = "Test"};
f.Controls.Add(button);
Application.Run(f);
Every Control has a Controls collection to which other Controls can be added (not just things you think of as "things that have child controls, like Panel or GroupBox" - some controls are collections of other controls, like a NumericUpDown is a textbox and a couple of buttons)
For an example of how much code you'll need to write, lay out a reasonable looking UI in the design view and then open the Form1.Designer.cs - you'll see why we do it with the aid of a design tool! :)
Wouldn't it be faster to learn if I didn't use the Designer tool?
IMO, no. That's like saying "wouldn't it be faster to learn if I hand code an SVG in notepad rather than using Inkscape/Gimp to draw the image visually.. or create a PNG by typing the bytes out in a hex editor"
Getting so close to the raw low level means you end up "not being able to see the wood for the trees" and it hinders your learning. For a lengthy discourse on abstractions and why we use them/how they apply to every daily process including learning and operating in life, see the comment trail
You need to add the button to your Form, not to the Main method!
The issue with your code is that it's in the wrong place - actually, it only runs after the form is closed, because Application.Run will run your form in a message loop, allowing UI events to fire.
You can either use the Visual Studio WinForms Designer (if using Visual Studio), or manually add the code after the InitializeComponent() method - so, either right in the constructor, or in any of the Form startup events, such as Load or Shown.
It's likewise very important to add the Button (or any dynamically instantiated control, for that matter) to the Controls collection of the Form - otherwise, your Button won't be displayed:
Button button = new Button {Height = 100, Width = 100, Text = "Test"};
this.Controls.Add(button);
There are certainly use cases for dynamic generation of controls; however, it's very unusual to build out your controls manually before the form even runs - in most cases of dynamic control generation, the form is up and running - the dynamic generation is in response to some user action. I recommend using the designer for general UI layout.

Multiple forms one windows C# possible or only panels/usercontrol?

So here's my Question, I'm new to C#(teaching my self at that) Here's the thing, I'm working on a basic sim game, nothing to complex but I've got the design and basic functions done.
However In order to implement it, I'm currently using multiple Forms(Visual Studio 2013)
I have my "main" form which has the "action" buttons to it
So when i want to go to a user Profile page I have
Btn_profileview Click(object sender, EventArgs e){
Form profile = new Form();
profile.Show();
}
The User would then implement the changes(for instance change name) which is written to a text file, for use in other areas of the program.
However It opens a new windows, I've tried modal and nonmodal windows and while the benefit of Modal so they have to actual close the window solves the issue, i'd rather have it just overwrite the preexisting Form, and then on close go back to the "main" screen without actually using multiple windows.
Now I was told UserControl and/or Panel would solve the issue, but it would cause a complete redesign moving from the multiple forms to the multiple panel screens and figuring out how to get those to work(Visible and Invisible), i'm assuming it wouldn't be extremely difficult something along the lines of Panel"name".show(); and panel"name".close();
But would it be possible to actually add a line of code to the pre-existing code(so as not to cause a complete reesign) or are Panels and UserControl the only real way to implement within 1 continuous windows?
paqogomez is right: There are many ways to do it.
Here is one that combines a lot of the pros:
You create an invisible Tab on your window with as many pages as you need. Place a Panel on each tab and create all your controls on of them. This does not mean that you have to do it all over - you can move and drop the controls you already have without much hassle. Of course you need to turn off docking and maybe anchors, but other than that this is a simple process.
If you have controls on the 2nd form with the same name, these names should be changed to something unique though. I hope all Controls have proper names already, but especially Labels get neglected, at least here.. (With a little luck you can even use cut and paste to get Controls from another form to panel2!)
The big pro of this trick is that you can do all work in the designer of the same form. The Tab control serves only as a container where you keep your panels without adding to the UI and without giving the user control of what is shown.
Next you create one Panel variable in your main form:
Panel currentPanel;
On Load you assign the first 'real' Panel to it like this:
currentPanel = panel1;
this.Controls.Add(currentPanel);
Later, each time you want to switch, you re-assign the panels you need like this:
this.Controls.Remove(currentPanel);
currentPanel = panel2; // or whichever panel you want to show..
this.Controls.Add(currentPanel );
If your real panels are docked to fill the tabpage, as they should, the currentPanel will fill the form. You still have access to each panel and to each control by their names at any time but you see no overhead of tabs and your form never changes, except for the full content.

How to create navigation inside program Form

Warning! This is noob question probably! Sorry in advance.
I'm learning C# (using MS Studio 2013) and I'm having hard time creating some kind of decent navigation in simple desktop program.
Basically what I want is this: MenuStrip with options like "calculate something", "Calculate somethingelse"... and other (that I can easily add later - like dynamic menu on a webpage). If you click first option inside the Form connected with the StripMenu you will get some controls that allows you to do something(like inputs on a webpage). If you click the second all these options will disappear and you will get a fresh set of controls where you can do somethingelse (simply another webpage to play with).
What is the best way to do it (I find it amazing hard to find out :) ). Only way I figured out (more from experience in js then tutorials) is to use show/hide like in javascript/html.
ExamplePanel.Visible = false;
ExampleOtherPanel.Visible = true;
But this doesn't seem right - I think it would be impossible to manage in bigger program (not only in code, but visual designer too - you can only fit that much Panels inside Form).
Any advice? Or at least a link to material where I can find out?
EDIT:
Finaly I gave up and used multiple Forms as sugested in answer.
private void MenuStripExample_Click_1(object sender, EventArgs e)
{
SomeForm SomeForm = new SomeForm();
this.Hide(); //Hide the main form before showing the secondary
SomeForm.ShowDialog(); //Show secondary form, code execution stop until SomeForm is closed
//this.Show(); //You may uncomment this if you want to have the previous Form to get back after you close new one
}
You normaly don't hide and show panels with different layouts. This is not a good design.
If you have complete different navigations/control sets, then create a new Form which is responsible for the control set.
If you don't want to use new Forms take a look at the TabControl.
You may also want to take a look at MDI-Container. You can use a Form as a MDI-Container and display various other Forms as child-elements inside of this container.

Monodevelop: Porting from C#/Visual Studio: Double Click disappear

For the last 2 month I've written application in C# in Visual Studio. Now i have to port that application to Linux by Monodevelop. Well, I already solved most of the porting errors, but there is one that i cant figure out. All double click and mouse double click events from Visual Studio stopped working - I even created small 1-form application that i ported to Mono with only form and one event (double click) - it also didnt work - so that means Monodevelop cant port double click events from Visual Studio ? I already checked WND_Proc function and Linux dont throw up any corresponding double-click event (it was 515 for in window and 3 hundred something on title bar...). Im already giving up and preparing for writing additional code to fix all double-click issue in my code but maybe someone has an answer.
Im using Ubuntu linux (if its neccesary i might tommorow check kernel version), MONO: 2.8.3, Visual Studio 2008 and project in .NET 3.5.
When implementing mouse clicks, there are two main differences between Windows and Gtk# that you should keep in mind:
Gtk# does not offer a 'double-click' signals ('Events' in Windows lingo), but only single 'click' signals. However Gdk library does implements both double-click and triple-click with its EventButton class!
Gtk# differentiates between Widgets (or 'Controls' in Windows lingo) and 'Containers' (there is no direct comparable in Windows). Most widgets placed on a Gtk# form will NOT receive mouse click events. In order to receive a mouse event you need to place the widget inside a specific container - like EventBox.
Here is how you do it Gtk#:
A. Add an EventBox containter to your form (in the example below: eventbox1). You can place it behind other Widgets or since it is not visible, unless you specifically select it to be (or change its background color). You can put a widget inside the EventBox, but you are limited to only one widget, that will also get the shape and size of the EventBox.
B. Add to this EventBox the signal 'ButtonPressEvent' out of the "Common Widget Signals" (in the example below: OnEventbox1ButtonPressEvent)
Every time a mouse button (left, middle or center or a combination) is clicked inside the EventBox, it will trigger this event and the function OnEventbox1ButtonPressEvent() will be called. If you need to identify the button that was clicked while handling this event, use the uint value in: args.Event.Button typically '1' will be the left mouse button, '2' the center button and '3' the right button ('2' might be also when both left and right buttons are clicked).
By the way, mouse motion events (without a button press) are not sent by default. So if you need to sense them you will need to add the PointMotionMask as well in the first like of the code example below.
Here is a code example of the ButtonPress Event Handler (the EventBox name is 'eventbox1') catching a double-click event using the EventButton class:
// The following line is may not be needed but is here to show how to do it
eventbox1.GdkWindow.Events = eventbox1.GdkWindow.Events | Gdk.EventMask.ButtonPressMask;
protected void OnEventbox1ButtonPressEvent (object o, ButtonPressEventArgs args)
{
if( ((Gdk.EventButton)args.Event).Type == Gdk.EventType.TwoButtonPress)
System.Media.SystemSounds.Beep.Play (); // Play a sound only if this is a double-click event
}
The order of the events received (in case of a double click) is:
Gdk.EventType.ButtonPress
Gdk.EventType.ButtonRelease
Gdk.EventType.ButtonPress
Gdk.EventType.TwoButtonPress
Gdk.EventType.ButtonRelease
Hope that helps!
GTK# treats double-click events differently than Windows Forms. You're going to have to write code to translate the events. If you're doing that, you may as well spend the time arguing against double-click as an idiom.

Creating a Popup Balloon like Windows Messenger or AVG

How can I create a Popup balloon like you would see from Windows Messenger or AVG or Norton or whomever?
I want it to show the information, and then slide away after a few seconds.
Edit: It needs to be blocking like Form.ShowDialog() because the program exits after displaying the notification
You can use the notifyIcon control that's part of .NET 2.0 System.Windows.Forms. That allows you to place an icon for your application in the System Tray. Then, you can call the ShowBalloonTip(int timeOut) method on that. Be sure however to first set the text, and icon properties on the notifyIcon for it to work. Small code sample:
private void button1_Click(object sender, EventArgs e)
{
this.notifyIcon1.BalloonTipText = "Whatever";
this.notifyIcon1.BalloonTipTitle = "Title";
this.notifyIcon1.Icon = new Icon("icon.ico");
this.notifyIcon1.Visible = true;
this.notifyIcon1.ShowBalloonTip(3);
}
EDIT: Ok, so notifyIcon won't work for you. My second suggestion would then be to create your own control for this. Actually, I would use a form. A simple form, with no borders, and no control box and just have a timer running so you can set the Opacity for fade in/out. Then, you can easily get the bottom right of the screen using the Rectangle Screen.PrimaryScreen.WorkingArea. Then just show your form at that position.
Don't create a modal (blocking) balloon. Please. A big part of the design of these UIs is that they are not dialogs: they're transient, potentially non-interactive elements, intended to provide incidental information to a user without necessarily interrupting their workflow. A balloon that steals focus and blocks user input would be irritating at best - if you need a dialog, then use a dialog.
The .NET 1.1 Visual Basic Power Pack had a toaster control.

Categories