How can I make floating windows use their design size (and not the Dock Panel Suite's default size) with the Weifenluo Dock Panel suite?
Hint: I tried a proposition from the Dock Panel Suite forums at SF.net, but that doesn't seem to work.
I stumbled across this question when looking for the answer myself, and found Timothy's answer to not work for me.
The problem was that the method he outlines also floated the window by default. (maybe that's a version difference)
I have solved this another way. I've created a base class that inherits from DockContent that all my document windows would inherit from. I then created another overload for the Show method that handles this (I used the DockPanelSuite source code to help build this method).
public void Show(DockPanel dockPanel, DockState dockState, Rectangle floatWindowBounds)
{
Show(dockPanel, dockState); //shows the panel like normal
//now for the part to initialize the float pane and size
if (DockHandler.FloatPane == null)
{
DockHandler.FloatPane = dockPanel.DockPaneFactory.CreateDockPane(this, DockState.Float, false);
DockHandler.FloatPane.FloatWindow.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
}
DockHandler.FloatPane.FloatWindow.Bounds = floatWindowBounds;
}
when CForm is derived from DockContent,
I have a method within my MDIContainerWindow which looks like this
public void ShowForm(CForm pForm)
{
pForm.MdiParent = this;
Size lS = pForm.Size;
dockPanel.DefaultFloatWindowSize = lS;
pForm.Show(dockPanel);
pForm.VisibleState = DockState.Float;
}
This is working for me (in VB):
Dim MyForm As New MyForm
MyForm.Show(DockPanel, New Rectangle(MyForm.Location, MyForm.Size))
MyForm.DockState = DockState.DockRight
This worked for me:
var topLeft = dockPanel1.Location;
topLeft.X += (dockPanel1.Size.Width / 2 - newForm.Size.Width / 2);
topLeft.Y += (dockPanel1.Size.Height / 2 - newForm.Size.Height / 2);
newForm.Show(dockPanel1, new Rectangle(topLeft, newForm.Size));
Related
Using Forms9Patch in Xamarin Forms I am able to have the font dynamically resize when running on UWP and changing the size of the window horizontally. It resizes perfectly.
However, I have a few issues that I'm not figuring out ...
When I shrink the window vertically, the text is not resized. I'm doing the
Lines = 1;
AutoFit = Forms9Patch.AutoFit.Width;
LineBreakMode = LineBreakMode.NoWrap;
I went back here - https://baskren.github.io/Forms9Patch/guides/Label.html and re-read it. It says to impose bounds autofitting to achieve this. I've tried and can't get it to work. What's the proper syntax to get this to work?
The starting font size for the label. I'm hard coding that right now. Is there a way to dynamically size it on startup?
I have a work around, but is there a built in way that Forms9Patch deals with screen scaling?
Alternatively, you could try to use something like this, where you add your private field label inside a ContentView, and then add a SizeChanged event to it
ContentView contentView = new ContentView
{
Content = label
};
contentView.SizeChanged += OnContentViewSizeChanged;
and in the event
void OnContentViewSizeChanged(object sender, EventArgs args)
{
string text = "Is this question similar to what you get asked at work? Learn more about asking and sharing private information with your coworkers using Stack Overflow for Teams. Is this question similar to what you get asked at work? Learn more about asking and sharing private information with your coworkers using Stack Overflow for Teams.";
View view = (View)sender;
// Line height is 1.2 if it's iOS or Android, but 1.3 for UWP
double lineHeight = 1.3;
double charWidth = 0.5;
text = String.Format(text, lineHeight, charWidth, view.Width, view.Height);
int charCount = text.Length;
int fontSize = (int)Math.Sqrt(view.Width * view.Height / (charCount * lineHeight * charWidth));
int lineCount = (int)(view.Height / (lineHeight * fontSize));
int charsPerLine = (int)(view.Width / (charWidth * fontSize));
label.Text = text;
label.FontSize = fontSize;
}
Here's some official documentation that recommends it
I am trying to implement a "Fillable Form" in which editable text fields appear over top of an image of a pre-preprinted form for a dot matrix printer. (using c# and Windows Forms and targeting .Net 2.0) My first idea was to use the image as the Windows Form background, but it looked horrible when scrolling and also did not scroll properly with the content.
My next attempt was to create a fixed-size window with a panel that overflows the bounds of the window (for scrolling purposes.) I added a PictureBox to the panel, and added my textboxes on top of it. This works fine, except that TextBoxes do not support transparency, so I tried several methods to make the TextBoxes transparent. One approach was to use an odd background color and a transparency key. Another, described in the following links, was to create a derived class that allows transparency:
Transparency for windows forms textbox
TextBox with a Transparent Background
Neither method works, because as I have come to find out, "transparency" in Windows Forms just means that the background of the window is painted onto the control background. Since the PictureBox is positioned between the Window background and the TextBox, it gives the appearance that the TextBox is not transparent, but simply has a background color equal to the background color of the Window. With the transparency key approach, the entire application becomes transparent so that you can see Visual Studio in the background, which is not what I want. So now I am trying to implement a class that derives from TextBox and overrides either OnPaint or OnPaintBackground to paint the appropriate part of the PictureBox image onto the control background to give the illusion of transparency as described in the following link:
How to create a transparent control which works when on top of other controls?
First of all, I can't get it working (I have tried various things, and either get a completely black control, or just a standard label background), and second of all, I get intermittent ArgumentExceptions from the DrawToBitmap method that have the cryptic message "Additional information: targetBounds." Based on the following link from MSDN, I believe that this is because the bitmap is too large - in either event it seems inefficient to capture the whole form image here because I really just want a tiny piece of it.
https://msdn.microsoft.com/en-us/library/system.windows.forms.control.drawtobitmap(v=vs.100).aspx
Here is my latest attempt. Can somebody please help me with the OnPaintBackground implementation or suggest a different approach? Thanks in advance!
public partial class TransparentTextbox : TextBox
{
public TransparentTextbox()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
//base.OnPaintBackground(e); // not sure whether I need this
if (Parent != null)
{
foreach (Control c in Parent.Controls)
{
if (c.GetType() == typeof(PictureBox))
{
PictureBox formImg = (PictureBox)c;
Bitmap bitmap = new Bitmap(formImg.Width, formImg.Height);
formImg.DrawToBitmap(bitmap, formImg.Bounds);
e.Graphics.DrawImage(bitmap, -Left, -Top);
break;
}
}
Debug.WriteLine(Name + " didn't find the PictureBox.");
}
}
}
NOTE: This has been tagged as a duplicate, but I referenced the "duplicate question" in my original post, and explained why it was not working. That solution only works if the TextBox sits directly over the Window - if another control (such as my Panel and PictureBox) sit between the window and the TextBox, then .Net draws the Window background onto the TextBox background, effectively making its background look gray, not transparent.
I think I have finally gotten to the bottom of this. I added a Bitmap variable to my class, and when I instantiate the textboxes, I am setting it to contain just the portion of the form image that sits behind the control. Then I overload OnPaintBackground to display the Bitmap, and I overload OnPaint to manually draw the text string. Here is the updated version of my TransparentTextbox class:
public partial class TransparentTextbox : TextBox
{
public Bitmap BgBitmap { get; set; }
public TransparentTextbox()
{
InitializeComponent();
SetStyle(ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
}
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.DrawString(this.Text, this.Font, Brushes.Black, new PointF(0.0F, 0.0F));
}
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.DrawImage(BgBitmap, 0, 0);
}
}
... and here is the relevant part of how I instantiate:
Bitmap bgImage = (Bitmap)Bitmap.FromStream(Document.FormImage);
PictureBox pb = new PictureBox();
pb.Image = bgImage;
pb.Size = pb.Image.Size;
pb.Top = 0;
pb.Left = 0;
panel1.Controls.Add(pb);
foreach (FormField field in Document.FormFields)
{
TransparentTextbox tb = new TransparentTextbox();
tb.Width = (int)Math.Ceiling(field.MaxLineWidth * 96.0);
tb.Height = 22;
tb.Font = new Font("Courier", 12);
tb.BorderStyle = BorderStyle.None;
tb.Text = "Super Neat!";
tb.TextChanged += tb_TextChanged;
tb.Left = (int)Math.Ceiling(field.XValue * 96.0);
tb.Top = (int)Math.Ceiling(field.YValue * 96.0);
tb.Visible = true;
Bitmap b = new Bitmap(tb.Width, tb.Height);
using (Graphics g = Graphics.FromImage(b))
{
g.DrawImage(bgImage, new Rectangle(0, 0, b.Width, b.Height), tb.Bounds, GraphicsUnit.Pixel);
tb.BgBitmap = b;
}
panel1.Controls.Add(tb);
}
I still need to work on how the text looks when I highlight it, and other things like that, but I feel like I am on the right track. +1 to Reza Aghaei and Mangist for commenting with other viable solutions!
I've just started learning UWP app development on Windows 10 Pro using Visual Studio 2015 Community Edition. I tried to modify the C# version of the official "Hello, World!" sample by setting the Width and Height attributes of the Page tag in MainPage.xaml.
Interestingly, when I start the app, its size will be different. Moreover, if I resize its window and then restart it, the app seems to remember its previous window size.
Is it possible to force a UWP app to have a predefined window size, at least on desktop PCs?
Try setting PreferredLaunchViewSize in your MainPage's constructor like this:
public MainPage()
{
this.InitializeComponent();
ApplicationView.PreferredLaunchViewSize = new Size(480, 800);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
}
As #kol also pointed out, if you want any size smaller than the default 500x320, you will need to manually reset it:
ApplicationView.GetForCurrentView().SetPreferredMinSize(new Size(200, 100));
You don't really have control over the window size, and even if you will try to re-size it it may fail. I've asked the same question on MSDN forums and got the answer here:
Windows 10 universal DirectX application
BTW, here is the solution in your event handler "OnLaunched" or in your Event Handler "OnActivated" find:
Window.Current.Activate();
And replace it with:
float DPI = Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi;
Windows.UI.ViewManagement.ApplicationView.PreferredLaunchWindowingMode = Windows.UI.ViewManagement.ApplicationViewWindowingMode.PreferredLaunchViewSize;
var desiredSize = new Windows.Foundation.Size(((float)800 * 96.0f / DPI), ((float)600 * 96.0f / DPI));
Windows.UI.ViewManagement.ApplicationView.PreferredLaunchViewSize = desiredSize;
Window.Current.Activate();
bool result = Windows.UI.ViewManagement.ApplicationView.GetForCurrentView().TryResizeView(desiredSize);
It is better if you place this code into the "OnActivated()" event handler as it will set your defined size when the app starts and when it becomes active after any interruptions.
In the "desiredSize" calculation, 800 is the width and 600 is the height. This calculation is needed, because the size is in DPI, so you have to convert it from pixels to DPI.
Also keep in mind that size cannot be smaller than "320x200".
For the very first app launch, the ApplicationView.PreferredLaunchWindowingMode is set to ApplicationViewWindowingMode.Auto regardless of what you set in your code.
However, from this question on MSDN, there may be a way to overcome this. One of the answers gives a way to set that very first launch size (reverting to Auto after that).
If your goal is to launch only once at a PreferredLaunchViewSize, you can use this rude solution (up to you for a better implementation with your coding style! :P)
public MainPage()
{
this.InitializeComponent();
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
if (localSettings.Values["launchedWithPrefSize"] == null)
{
// first app launch only!!
ApplicationView.PreferredLaunchViewSize = new Size(100, 100);
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
localSettings.Values["launchedWithPrefSize"] = true;
}
// resetting the auto-resizing -> next launch the system will control the PreferredLaunchViewSize
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.Auto;
}
}
P.S. I have not tested this.
In this other link here in StackOverflow, there is another way to do it: https://stackoverflow.com/a/68583688/5993426. This code is to insert in the App.xaml:
protected override void OnWindowCreated(WindowCreatedEventArgs args)
{
SetWindowMinSize(new Size(args.Window.Bounds.Width, args.Window.Bounds.Height));
args.Window.CoreWindow.SizeChanged += CoreWindow_SizeChanged;
base.OnWindowCreated(args);
}
private void CoreWindow_SizeChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.WindowSizeChangedEventArgs args)
{
if (SetWindowMinSize(args.Size))
{
sender.ReleasePointerCapture();
}
}
private bool SetWindowMinSize(Size size)
{
if (size.Width < minWidth || size.Height < minHeight)
{
if (size.Width < minWidth) size.Width = minWidth + 10;
if (size.Height < minHeight) size.Height = minHeight + 10;
return ApplicationView.GetForCurrentView().TryResizeView(size);
}
return false;
}
I have a C# WinForms application and when I give the executable to different users the application displays in different sizes (based on their screen resolution). Some of the parts of the application can't be seen.
how can I set absolute 1280X800 for my forms and make sure that the form size will not be changed whatever resolution is!
You can use Control.ScaleControl and Control.Scale
private void MainForm_Load( object sender, EventArgs e )
{
float width_ratio = (Screen.PrimaryScreen.Bounds.Width / 1280);
float heigh_ratio = (Screen.PrimaryScreen.Bounds.Height / 800f);
SizeF scale = new SizeF(width_ratio, heigh_ratio);
this.Scale(scale);
//And for font size
foreach (Control control in this.Controls)
{
control.Font = new Font("Microsoft Sans Serif", c.Font.SizeInPoints * heigh_ratio * width_ratio);
}
}
Hope this helps.
Use the MaximumSize property of the form.
form.MaximumSize = new Size(1280, 800);
You can also set a MinimumSize if you don't want the user to make it smaller than a desired size.
You can instead design the GUI so it scrolls up and down more easily.You can make use of the following
Layout Managers
Docking
Anchors
The property
Screen.PrimaryScreen.WorkingArea
is very useful for form sizing and positioning. For example this code:
this.Width = Screen.PrimaryScreen.WorkingArea.Width/2;
this.Height = Screen.PrimaryScreen.WorkingArea.Height/2;
this.Top = (Screen.PrimaryScreen.WorkingArea.Top + Screen.PrimaryScreen.WorkingArea.Height)/4;
this.Left = (Screen.PrimaryScreen.WorkingArea.Left + Screen.PrimaryScreen.WorkingArea.Width)/4;
will place the form in which it is executed in the middle of the screen and size it to half the screen.
The WorkingArea var is used to exclude stuff like the task bar and other docked items on the desktop when calculating the size of the screen.
Hope this helps.
I have noticed that some applications change their controls' positions to fit themselves as much as possible in the current resolution. For example, if the window is maximized, the controls are set in such a way that the overall GUI looks balanced.
Is it possible to make or implement this functionality in Visual studio 2010 using C#?
Use Dock and Anchor properties. Here is a good article. Note that these will handle changes when maximizing/minimizing. That is a little different that if the screen resolution changes, but it will be along the same idea.
Use combinations of these to get the desired result:
Set Anchor property to None, the controls will not be resized, they only shift their position.
Set Anchor property to Top+Bottom+Left+Right, the controls will be resized but they don't change their position.
Set the Minimum Size of the form to a proper value.
Set Dock property.
Use Form Resize event to change whatever you want
I don't know how font size (label, textbox, combobox, etc.) will be affected in (1) - (4), but it can be controlled in (5).
float widthRatio = Screen.PrimaryScreen.Bounds.Width / 1280;
float heightRatio = Screen.PrimaryScreen.Bounds.Height / 800f;
SizeF scale = new SizeF(widthRatio, heightRatio);
this.Scale(scale);
foreach (Control control in this.Controls)
{
control.Font = new Font("Verdana", control.Font.SizeInPoints * heightRatio * widthRatio);
}
..and to detect a change in resolution to handle it (once you're using Docking and Anchoring like SwDevMan81 suggested) use the SystemEvents.DisplaySettingsChanged event in Microsoft.Win32.
sorry I saw the question late,
Here is an easy programmatically solution that works well on me,
Create those global variables:
float firstWidth;
float firstHeight;
after on load, fill those variables;
firstWidth = this.Size.Width;
firstHeight = this.Size.Height;
then select your form and put these code to your form's SizeChange event;
private void AnaMenu_SizeChanged(object sender, EventArgs e)
{
float size1 = this.Size.Width / firstWidth;
float size2 = this.Size.Height / firstHeight;
SizeF scale = new SizeF(size1, size2);
firstWidth = this.Size.Width;
firstHeight = this.Size.Height;
foreach (Control control in this.Controls)
{
control.Font = new Font(control.Font.FontFamily, control.Font.Size* ((size1+ size2)/2));
control.Scale(scale);
}
}
I hope this helps, it works perfect on my projects.
Here I like to use https://www.netresize.net/index.php?c=3a&id=11#buyopt. But it is paid version.
You also can get their source codes if you buy 1 Site License (Unlimited Developers).
How ever I am finding the nuget package solution.
add this code at page load do for all control or add all control in containers
int x;
Point pt = new Point();
x = Screen.PrimaryScreen.WorkingArea.Width - 1024;
x = x / 2;
pt.Y = groupBox1.Location.Y + 50;
pt.X = groupBox1.Location.X + x;
groupBox1.Location = pt;
in the form load event add this line
this.WindowState = FormWindowState.Maximized;
private void MainForm_Load( object sender, EventArgs e )
{
this.Size = Screen.PrimaryScreen.WorkingArea.Size
}
this.WindowState = FormWindowState.Maximized;