c#: Window Forms: Retrieve child control values from unactivated tab - winforms

I have a winform with a tab control. On the default tab I have a 'go' button tied to a function that retrieves the values from textboxes on the second tab(default values).
The values come up as "" if I don't first look at the 2nd tab which i'm guessing causes the textboxes to be poulated with the default values.
How do I make the form fill all it's controls on load?

Data Binding doesn't work on invisible control. I found it here. For reference look at this MSDN thread

This works like a charm:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
ComboBox c = new ComboBox();
Button b = new Button();
public Form1()
{
InitializeComponent();
b.Text = "New Button";
b.Click += new EventHandler(b_Click);
this.tabPage1.Controls.Add(b);
c.Items.Add("Hello World");
c.Items.Add("My Program");
c.SelectedIndex = 0;
this.tabPage2.Controls.Add(c);
}
void b_Click(object sender, EventArgs e)
{
MessageBox.Show(c.Text.ToString());
}
}
}
If not specified at load time the combox listindex defaults to -1 which is "" (blank) so if you know the exact index at which your default values get displayed in the combo box then set the listindex to that index.
Using the code below the first item in the combobox will get selected at run time.
comboBox1.SelectedIndex = 0 (The first item in the combo box)

Related

WPF Radio button does not update after several binding

I have an application that allows users to move forward and backward
And the radio button is implemented like following:
For the first 4 times, I change the selected item for the radio button and then move next and then come back and do the same, the radio buttons work fine and the model is updated correctly as its GUI. However, after the first 4 times moving forwards and backwards, the radio buttons do not update its GUI.
Following is the navigation system:
Model and view are bound based on Next/Back button
Check boxs works fine!
Please give me some suggestions.
Thanks in advance
I finally found the answer:
If you have tried to bind the RadioButton’s IsChecked property in WPF to an object, you have most likely experienced the following problem: In OneWay bindings it works great. But if you have more than one RadioButtons binded TwoWay and you click on an unchecked one, you were expecting that the object to which the previously checked RadioButton was binded to receive the value of False. But you were wrong in your expectations. That’s because for some reasons Microsoft does not obey bindings and does not pass the False value to the DependencyProperty and instead of that they just assign the value False directly to the property, which ruins the binding.
There are many proposed solutions to this around the internet, problem with all those is that they do not work with dynamically generated controls. So since I had to find a way to make this working with dynamic controls, decided to make a wrapper of the real RadioButton which will correctly Bind in two ways. Here is the code for the wrapper:
using System;
using System.IO;
using System.Printing;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using Microsoft.Win32;
namespace Controls
{
public class RadioButtonExtended : RadioButton
{
static bool m_bIsChanging = false;
public RadioButtonExtended()
{
this.Checked += new RoutedEventHandler(RadioButtonExtended_Checked);
this.Unchecked += new RoutedEventHandler(RadioButtonExtended_Unchecked);
}
void RadioButtonExtended_Unchecked(object sender, RoutedEventArgs e)
{
if (!m_bIsChanging)
this.IsCheckedReal = false;
}
void RadioButtonExtended_Checked(object sender, RoutedEventArgs e)
{
if (!m_bIsChanging)
this.IsCheckedReal = true;
}
public bool? IsCheckedReal
{
get { return (bool?)GetValue(IsCheckedRealProperty); }
set
{
SetValue(IsCheckedRealProperty, value);
}
}
// Using a DependencyProperty as the backing store for IsCheckedReal. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsCheckedRealProperty =
DependencyProperty.Register("IsCheckedReal", typeof(bool?), typeof(RadioButtonExtended),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal |
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
IsCheckedRealChanged));
public static void IsCheckedRealChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
m_bIsChanging = true;
((RadioButtonExtended)d).IsChecked = (bool)e.NewValue;
m_bIsChanging = false;
}
}
}
So now all you have to do is to use the ExtendedRadioButton instead of the built-in one and bind to the IsCheckedReal property instead of the IsChecked one.
Enjoy 🙂

Picturebox and button click

Ran into a confusing problem. I need to make a fishtank in Windows forms. Every time a button is clicked, a fish will appear. I thought about putting code in button_click function. The problem is that the picturebox with the image doesn't appear when I click the button.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
BackColor = System.Drawing.Color.LightBlue;
}
private void button1_Click(object sender, EventArgs e)
{
//PictureBox pb = new System.Windows.Forms.PictureBox();
PictureBox pb = new PictureBox();
pb.Image = Image.FromFile("C:\\Users\\Elonas\\Desktop\\FishTank\\Photo\\Fish_right.png");
pb.Location = new Point(300, 300);
}
}
}
Every time you create a control (pb, in this case), you have to add it to the Controls collection of the form before you can see it.
You can also replace pb.image in the picturebox instead of creating a new picturebox every mouse click. You still need to add it to the form's controls collection when you create it as new (or create it in the Designer).
Ow so something like this? Is this one of the controls? Never was I introduced. I get the idea. Ill try to work with that.
pb.Location = new Point(300, 300);

WPF Fullscreen in RibbonWindow

I created an application using Microsoft ribbon for WPF. I used RibbonWindow instead of simple Window to place QuickAccessToolbar to window header.
The problem is that normal Window becomes fullscreen when i set
WindowStyle="None"
WindowState="Maximized"
But RibbonWindow becomes bigger and its bottom part hides behind taskbar.
I suppose that the only difference between window and RibbonWindows is the controlTemplate.
But i dont actually understand how can i via template place the window above the taskbar.
Any ideas how to show my RibbonWindow above taskbar just as normal window does?
Link to the VS2010 project (10KiB) (Microsoft Ribbon For WPF isn't included)
RibbonWindow uses custom WindowChrome. That is the reason of incorrect behavior. Try this code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Microsoft.Windows.Shell;
namespace Utils
{
public static class WindowHelper
{
public static void Fullscreen(Window p_oWindow)
{
p_oWindow.WindowStyle = WindowStyle.None;
p_oWindow.Topmost = true;
p_oWindow.WindowState = WindowState.Maximized;
WindowChrome.SetWindowChrome(p_oWindow, null);
}
public static void UndoFullscreen(Window p_oWindow)
{
p_oWindow.WindowStyle = WindowStyle.SingleBorderWindow;
p_oWindow.Topmost = false;
p_oWindow.WindowState = WindowState.Normal;
WindowChrome.SetWindowChrome(p_oWindow, GetChrome());
}
public static WindowChrome GetChrome()
{
WindowChrome oCustomChrome = new WindowChrome();
oCustomChrome.CornerRadius = new System.Windows.CornerRadius(0, 0, 0, 0);
oCustomChrome.CaptionHeight = 0;
oCustomChrome.ResizeBorderThickness = new System.Windows.Thickness(2, 2, 2, 2);
return oCustomChrome;
}
}
}
The problem is the WindowStyle. This happens in all WPF windows when you remove the chrome. (They really optimized this feature for full-screen kiosk apps).
In order to handle maximizing your window to the correct size, you're going to need to handle it yourself. When you maximize button is clicked, you will need to get the working area of the current monitor you're on. There isn't a WPF way of doing this, but you can use the WinForms Screen class.
Your maximize method would look like so:
// you must save the restore bounds, since we never set Window.WindowState,
// so the RestoreBounds property will get set to the maximized bounds
private System.Drawing.Rectangle restoreBounds;
private void DoMaximize(object sender, EventArgs e)
{
var bounds = new System.Drawing.Rectangle((int)Left, (int)Top,
(int)ActualWidth, (int)ActualHeight));
var screen = System.Windows.Forms.Screen.FromRectangle(bounds);
var area = screen.WorkingArea;
restoreBounds = bounds;
Left = area.X;
Top = area.Y;
Width = area.Width;
Height = area.Height;
}

screenshot of a winforms control through C#

Is it possible to get a screenshot of a control in winforms without actually displaying it on the screen? How about a webBrowser component?
Yes. This can be done.
I whipped up a sample program to do it. Forgive my naming conventions and code organization, this was whipped up very quickly. You can modify it to better fit your needs, but this shows the basics.
I have a single form with three controls:
button1: Button with the default settings.
button2: Button with the Visible property set to false and the Text set to "button2 - not visible"
webBrowser1: WebBrowser control with the visibility set to false, set the size to 250, 101 (just so it fits on my form. The size is relevant when you look at the capture at the bottom of my answer. You'll need to size it accordingly.)
here's the code in Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
PrintInvisibleControl(button2, #"C:\button.jpg");
PrintInvisibleControl(webBrowser1, #"C:\webbrowser.jpg");
}
private void PrintInvisibleControl(Control myControl, string filename)
{
Graphics g = myControl.CreateGraphics();
//new bitmap object to save the image
Bitmap bmp = new Bitmap(myControl.Width, myControl.Height);
//Drawing control to the bitmap
myControl.DrawToBitmap(bmp, new Rectangle(0, 0, myControl.Width, myControl.Height));
bmp.Save(filename, ImageFormat.Jpeg);
bmp.Dispose();
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("http://www.microsoft.com");
}
}
}
This resulted in the following captures:

WPF: How can I programatically close a PrintDialog?

How can I programatically close a WPF PrintDialog? I tried to call Finalize on it trough reflection, and that does not close it either. Here is what I tried with:
using System;
using System.Reflection;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication15
{
partial class Window1 : Window
{
PrintDialog _printDialog;
public Window1()
{
InitializeComponent();
new Thread(OpenDialog).Start();
new Thread(CloseDialog).Start();
}
void OpenDialog()
{
Thread.Sleep(1000);
Dispatcher.BeginInvoke((Action)OpenDialogImpl);
}
void OpenDialogImpl()
{
_printDialog = new PrintDialog();
_printDialog.ShowDialog();
}
void CloseDialog()
{
Thread.Sleep(2000);
Dispatcher.BeginInvoke((Action)CloseDialogImpl);
}
void CloseDialogImpl()
{
var type = typeof(PrintDialog);
var flags = BindingFlags.Instance | BindingFlags.NonPublic;
var finalize = type.GetMethod("Finalize", flags);
finalize.Invoke(_printDialog, null);
MessageBox.Show("Finalized");
}
}
}
Internally, the PrintDialog class uses a Win32PrintDialog as a local variable to the ShowDialog() method, which in turn ends up uses the windows common dialog. Using reflection to get at something to close it might be futile, or at least maddening.
Just a stretch, as I haven't used it, but it might be possible to use White to issue a button press to the dialog's Cancel button. UISpy (mentioned on the White page) might be handy towards that end, too.

Resources