How to center MDI child Form? - c#

I have this code, to add a new child:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
Point centerPoint = new Point((Container.ActualWidth / 2) - (500/2), (Container.ActualHeight / 2) - (400 / 2));
MdiChild newForm = new MdiChild();
newForm.Title = "My Form";
newForm.Content = new MyForm1();
newForm.Width = 500;
newForm.Height = 400;
newForm.Resizable = false;
newForm.MaximizeBox = false;
newForm.Position = centerPoint;
Container.Children.Add(newForm);
}
This code is for the view:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
xmlns:mdi="clr-namespace:WPF.MDI;assembly=WPF.MDI"
Title="WPF.MDI Example" Height="362" Width="684" WindowState="Maximized">
<DockPanel>
<mdi:MdiContainer Name="Container" Background="#FF474040" >
<mdi:MdiContainer.Menu>
<Menu DockPanel.Dock="Top" Width="677">
<MenuItem Header="Menu1" click="Menu1_Click">
</mdi:MdiContainer.Menu>
</mdi:MdiContainer>
</DockPanel>
How can I center MDI child Form?
It always opens in the upper left side
I don't find the solution yet,
Thanks.
I also tried to put this code, in the code behind form child, but it doesn't works:
public partial class MyForm1: UserControl
{
BalanceEntities db = new BalanceEntities();
public MyForm1()
{
InitializeComponent();
this.HorizontalAlignment = HorizontalAlignment.Center;
this.VerticalAlignment = VerticalAlignment.Center;
}
}

You should use WindowStartupLocation property of the Window like this:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
Point centerPoint = new Point((Container.ActualWidth / 2) - (500/2), (Container.ActualHeight / 2) - (400 / 2));
MdiChild newForm = new MdiChild();
newForm .Title = "My Form";
//The code omitted for the brevity
newForm.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
Container.Children.Add(newForm);
}
OR:
this.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;

Thanks for James Thorpe, I solve my problem at this way:
private void Menu1_Click(object sender, RoutedEventArgs e)
{
MdiChild newForm = new MdiChild();
newForm.Title = "My Form";
newForm.Content = new MyForm1();
newForm.Width = 500;
newForm.Height = 400;
newForm.Resizable = false;
newForm.MaximizeBox = false;
Container.Children.Add(newForm);
// And then I add the position:
Point centerPoint = new Point((Container.ActualWidth / 2) - (newForm.Width / 2), (Container.ActualHeight / 2) - (newForm.Height / 2));
newForm.Position = centerPoint;
}
Thanks for the help.

Do the following , it worked for me
newForm.StartPosition = FormStartPosition.CenterScreen;

Related

Size New Window to Content and Center Relative to Main Window

I have a button that opens a New Window.
I want to fit the New Window to the dynamic content inside.
Then position it Center, relative to Main Window. So it follows the Main Window's location.
Not WindowStartupLocation.CenterScreen.
This is what I'm using. It doesn't quite work right.
XAML
The New Window is originally set to 900x500, but is overridden by SizeToContent.
<Window x:Class="MyProgram.NewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="New Window"
Width="900"
Height="500">
C#
This Button is on Main Window.
I use SizeToContent.Width.
newWindow.Width does not use the SizeToContent's width, but instead detects the XAML width 900.
This causes the New Window to always be off center.
I tried setting the XAML width to Auto or 1, it still goes off center a different direction.
I tried using double width = Convert.ToInt32(SizeToContent.Width); but it says the width is 1.
I ran newWindow.UpdateLayout() but it didn't work. https://stackoverflow.com/a/2149676/6806643
public static NewWindow newWindow;
private Boolean IsNewWindowOpened = false;
private void btnNeWindow_Click(object sender, RoutedEventArgs e)
{
// Check if Window is already open
if (IsNewWindowOpened) return;
newWindow = new NewWindow(this);
// Only allow 1 Window instance
newWindow.ContentRendered += delegate { IsNewWindowOpened = true; };
newWindow.Closed += delegate { IsNewWindowOpened = false; };
// Keep Window on Top
newWindow.Owner = Window.GetWindow(this);
// Fit Window to Content
newWindow.SizeToContent = SizeToContent.Width;
// Update Layout
newWindow.UpdateLayout()
// Detect which screen we're on
var allScreens = System.Windows.Forms.Screen.AllScreens.ToList();
var thisScreen = allScreens.SingleOrDefault(s => this.Left >= s.WorkingArea.Left && this.Left < s.WorkingArea.Right);
if (thisScreen == null) thisScreen = allScreens.First();
// Position Relative to MainWindow
newWindow.Left = Math.Max((this.Left + (this.Width - newWindow.Width) / 2), thisScreen.WorkingArea.Left);
newWindow.Top = Math.Max((this.Top + (this.Height - newWindow.Height) / 2), thisScreen.WorkingArea.Top);
// Open Window
newWindow.Show();
}
Examples
Off Center
Correctly Centered
Here is what I've done. Let me know if you have any improvements.
Main Window
Open New Window Button
public static NewWindow newWindow;
private Boolean IsNewWindowOpened = false;
private void btnNeWindow_Click(object sender, RoutedEventArgs e)
{
if (IsPreviewWindowOpened) return;
// Open Preview Window
previewWindow = new Preview(this);
// Only allow 1 Window instance
previewWindow.ContentRendered += delegate { IsPreviewWindowOpened = true; };
previewWindow.Closed += delegate { IsPreviewWindowOpened = false; };
// Keep Window on Top
previewWindow.Owner = Window.GetWindow(this);
// Size to Content
previewWindow.SizeToContent = SizeToContent.Width;
// Open Window
previewWindow.Show();
}
New Window
XAML
Window_Loaded
<Window x:Class="MyProgram.NewWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="New Window"
Width="900"
Height="500"
Loaded="Window_Loaded">
C#
Size Window to fit dynamic content.
Position Center, relative to Main Window.
Also nudges window back on screen if going off.
private void Window_Loaded(object sender, EventArgs e)
{
// Detect which screen we're on
var allScreens = System.Windows.Forms.Screen.AllScreens.ToList();
var thisScreen = allScreens.SingleOrDefault(s => this.Left >= s.WorkingArea.Left && this.Left < s.WorkingArea.Right);
if (thisScreen == null) thisScreen = allScreens.First();
// Position Relative to MainWindow
this.Left = Math.Max((mainwindow.Left + (mainwindow.Width - this.Width) / 2), thisScreen.WorkingArea.Left);
this.Top = Math.Max((mainwindow.Top + (mainwindow.Height - this.Height) / 2), thisScreen.WorkingArea.Top);
}

Printing Canvas using PrintDialog in WPF

I am trying to take the print of Canvas in A4 size by setting height and width to 29.7cm and 21cm respectively.
I am getting proper output on Windows 7 devices. But for Windows 10 devices, the print output is not same as Windows 7 devices.
The real problem is height and width is not maintained for Windows 10 devices.
Please Help and Suggest Me !!
Please find below code:
Xaml:
<Window x:Class="TestSolution.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
VerticalContentAlignment="Stretch"
HorizontalContentAlignment="Stretch"
Height="29.7cm"
Width="21cm"
ResizeMode="NoResize">
<Grid x:Name="grdTest"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Height="29.7cm"
Width="21cm">
<Canvas x:Name="cnvTest"
VerticalAlignment="Stretch"
Height="29.7cm"
Width="21cm"
HorizontalAlignment="Stretch">
</Canvas>
</Grid>
</window>
Code Behind
private void btn_Click(object sender, RoutedEventArgs e)
{
PrintDialog prnt = new PrintDialog();
if (prnt.ShowDialog() == true)
{
prnt.PrintVisual(cnvTest, "Printing Canvas");
}
this.Close();
}
Finally got the solution. courtesy Magnus (MM8)
Please find solution on the below link
https://social.msdn.microsoft.com/Forums/en-US/b26c7898-169a-4726-b582-e79dc63f8450/printing-canvas-using-printdialog-in-wpf?forum=wpf
Here is a copy of the answer from the site, assuming a canvas with the name cnvTest:
private void btn_Click(object sender, RoutedEventArgs e)
{
PrintDialog prnt = new PrintDialog();
if (prnt.ShowDialog() == true)
{
Size pageSize = new Size(prnt.PrintableAreaWidth, prnt.PrintableAreaHeight);
cnvTest.Measure(pageSize);
cnvTest.Arrange(new Rect(5, 5, pageSize.Width, pageSize.Height));
if (prnt.ShowDialog() == true)
{
prnt.PrintVisual(canvas, "Printing Canvas");
}
}
this.Close();
}
you can try this code
System.Windows.Controls.PrintDialog printDialog = new System.Windows.Controls.PrintDialog();
System.Drawing.Printing.PrinterSettings printer = new System.Drawing.Printing.PrinterSettings();
System.Printing.LocalPrintServer localPrintServer = new System.Printing.LocalPrintServer();
System.Printing.PrintTicket pt = new System.Printing.PrintTicket();
System.Printing.PrintQueue pq = new System.Printing.PrintQueue(localPrintServer, printer.PrinterName, System.Printing.PrintSystemDesiredAccess.AdministratePrinter);
System.Printing.PageMediaSize PMS = new System.Printing.PageMediaSize(canvas.ActualWidth + 20, canvas.ActualHeight + 20);
System.Windows.Size pageSize = new System.Windows.Size(canvas.ActualWidth+20, canvas.ActualHeight+20);
canvas.Arrange(new Rect(0, 0, pageSize.Width, pageSize.Height));
canvas.Measure(pageSize);
pt.PageMediaSize = PMS;
pt.PageMediaType = System.Printing.PageMediaType.Unknown;
pq.DefaultPrintTicket.PageMediaSize = PMS;
pq.DefaultPrintTicket.PageMediaType = System.Printing.PageMediaType.Unknown;
printDialog.PrintQueue = pq;
printDialog.PrintTicket = pt;
printDialog.PrintQueue.Commit();
if (printDialog.ShowDialog() == true)
{
printDialog.PrintVisual(canvas, "Test");
}

C# WPF. How to add Ellipces dynamically into canvas?

I'm trying to add some ellipces with random positions into my canvas, but i can see them on my canvas. Progmab is compilling quite saccesfull. Code:
for (int i = 0; i < FirefliesCount; ++i)
{
Firefly CurrentFirefly = new Firefly();
CurrentFirefly.Speed = Randomer.Next(1, 3);
CurrentFirefly.Body = new Ellipse();
CurrentFirefly.Body.Margin = new Thickness(Randomer.Next(10, (int)MainCanvas.Width - 10),
Randomer.Next(10, (int)MainCanvas.Height - 10),
0, 0);
CurrentFirefly.Body.Fill = Brushes.Black;
CurrentFirefly.Body.Height = MainCanvas.Height / 4;
CurrentFirefly.Body.Width = 1.5 * CurrentFirefly.Body.Height;
MainCanvas.Children.Add(CurrentFirefly.Body);
}
And Fireflie class:
class Firefly
{
public Ellipse Body { get; set; }
public int Speed { get; set; }
}
Probably you did not set the Width and Height properties of your MainCanvas; then they have the value NaN and therefore you will not see the ellipses.
My suggestion is to use ActualWidth and ActualHeight instead and to delay the adding of the ellipses until the canvas is loaded. Here is an example:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
MainCanvas.Loaded += MainCanvas_Loaded;
}
void MainCanvas_Loaded(object sender, RoutedEventArgs e)
{
Init();
}
private void Init()
{
const int FirefliesCount = 100;
Random Randomer = new Random();
for (int i = 0; i < FirefliesCount; ++i)
{
Firefly CurrentFirefly = new Firefly();
CurrentFirefly.Speed = Randomer.Next(1, 3);
CurrentFirefly.Body = new Ellipse();
CurrentFirefly.Body.Margin = new Thickness(Randomer.Next(10, (int)MainCanvas.ActualWidth - 10),
Randomer.Next(10, (int)MainCanvas.ActualHeight - 10),
0, 0);
CurrentFirefly.Body.Fill = Brushes.Black;
CurrentFirefly.Body.Height = MainCanvas.ActualHeight / 4;
CurrentFirefly.Body.Width = 1.5 * CurrentFirefly.Body.Height;
MainCanvas.Children.Add(CurrentFirefly.Body);
}
}
}
The corresponding xaml file looks like this:
<Window x:Class="WpfApplication7.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="MainCanvas"/>
</Window>

C# How to create a label onClick on a canvas

What I am looking for is for the user to
1. click on the canvas
2. a new label show up and the user can enter text.
3. When the user clicks elsewhere or hit enter the labels is finished editing.
This is what I have so far...
private void DrawingCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
Label lbl = new Label();
lbl.Content = "start typing";
//lbl.Left = location.X;
//lbl.Top = location.Y;
//lbl.Focus = Boolean.TrueString;
canvas.Children.Add(lbl);
}
Any help would be greatly appreciated, thanks!
Try like this
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas x:Name="cnvs" PreviewMouseLeftButtonUp="cnvs_MouseLeftButtonUp" Background="Transparent"></Canvas>
private void cnvs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
TextBox txtBox = new TextBox() {Width=80,AcceptsReturn=false };
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
}
I hope this will help.
UPDaTE:
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
TextBox txtBox = new TextBox() {AcceptsReturn=false ,BorderThickness=new Thickness(0)};
Binding b = new Binding("Text") { RelativeSource = new RelativeSource(RelativeSourceMode.Self) };
txtBox.SetBinding(TextBox.WidthProperty, b);
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
Try setting the textbox width to Double.NaN. This will give you an "Auto" width. To get rid of the border, set the textbox's borderthickness to 0. See below:
private void cnvs_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
var txtBox = new TextBox() { Width=Double.NaN, AcceptsReturn=false }; // auto width
txtBox.BorderThickness = new Thickness(0); // no border
canvas.Children.Add(txtBox);
Canvas.SetLeft(txtBox, point.X);
Canvas.SetTop(txtBox, point.Y);
txtBox.Focus();
}

Panel in a panel, autoscroll

I'm doing a minimalist test app after encountering an issue with my real program, using WinForms. I put a small panel (child) inside a bigger panel (parent). The bigger panel has AutoScroll set to true. The child panel has the default Anchors set to Top and Left. The child panel is not docked.
The behavior I want is for scrollbars to appear whenever the smaller panel's location is too offset, either top, bottom, left or right. The problem is that it only works when it's too far right, or too far in the bottom. No scrollbars appear when it's too much in the top or too much in the left directions.
I use two simple buttons to force the child panel's location 200 pixels to the left, or 200 pixels to the right to have a quick way of easily modifying its position.
Here's my Form1() code:
private void button1_Click(object sender, EventArgs e)
{
childPanel.Location = new Point(childPanel.Location.X - 200, childPanel.Location.Y);
hostPanel.Invalidate();
}
private void button2_Click(object sender, EventArgs e)
{
childPanel.Location = new Point(childPanel.Location.X + 200, childPanel.Location.Y);
hostPanel.Invalidate();
}
Here's the designer code:
private void InitializeComponent()
{
this.hostPanel = new System.Windows.Forms.Panel();
this.childPanel = new System.Windows.Forms.Panel();
this.moveChildLeft = new System.Windows.Forms.Button();
this.moveChildRight = new System.Windows.Forms.Button();
this.hostPanel.SuspendLayout();
this.SuspendLayout();
//
// hostPanel
//
this.hostPanel.AutoScroll = true;
this.hostPanel.BackColor = System.Drawing.SystemColors.AppWorkspace;
this.hostPanel.Controls.Add(this.childPanel);
this.hostPanel.Location = new System.Drawing.Point(239, 48);
this.hostPanel.Name = "hostPanel";
this.hostPanel.Size = new System.Drawing.Size(400, 400);
this.hostPanel.TabIndex = 0;
//
// childPanel
//
this.childPanel.BackColor = System.Drawing.SystemColors.ButtonHighlight;
this.childPanel.Location = new System.Drawing.Point(29, 62);
this.childPanel.Name = "childPanel";
this.childPanel.Size = new System.Drawing.Size(342, 259);
this.childPanel.TabIndex = 0;
//
// moveChildLeft
//
this.moveChildLeft.Location = new System.Drawing.Point(61, 81);
this.moveChildLeft.Name = "moveChildLeft";
this.moveChildLeft.Size = new System.Drawing.Size(75, 23);
this.moveChildLeft.TabIndex = 1;
this.moveChildLeft.Text = "Left 200";
this.moveChildLeft.UseVisualStyleBackColor = true;
this.moveChildLeft.Click += new System.EventHandler(this.button1_Click);
//
// moveChildRight
//
this.moveChildRight.Location = new System.Drawing.Point(61, 111);
this.moveChildRight.Name = "moveChildRight";
this.moveChildRight.Size = new System.Drawing.Size(75, 23);
this.moveChildRight.TabIndex = 2;
this.moveChildRight.Text = "Right 200";
this.moveChildRight.UseVisualStyleBackColor = true;
this.moveChildRight.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1018, 549);
this.Controls.Add(this.moveChildRight);
this.Controls.Add(this.moveChildLeft);
this.Controls.Add(this.hostPanel);
this.Name = "Form1";
this.Text = "Form1";
this.hostPanel.ResumeLayout(false);
this.ResumeLayout(false);
}
Yet - Another Winforms incapability quickly solved by WPF:
XAML:
<Window x:Class="WpfApplication4.Window3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window3" WindowState="Maximized">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Button Content="Left" Click="MoveLeft"/>
<Button Content="Right" Click="MoveRight"/>
</StackPanel>
<Border BorderBrush="Blue" BorderThickness="1" Width="300" Height="300">
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" x:Name="Scr">
<Grid Background="Green" Width="100" Height="100" x:Name="Grid"/>
</ScrollViewer>
</Border>
</DockPanel>
</Window>
Code behind:
using System.Windows;
namespace WpfApplication4
{
public partial class Window3 : Window
{
public Window3()
{
InitializeComponent();
}
private void MoveRight(object sender, RoutedEventArgs e)
{
if (Grid.Margin.Right <= 0)
{
Grid.Margin = new Thickness(Grid.Margin.Left + 100,0,0,0);
}
else
{
Grid.Margin = new Thickness(0, 0, Grid.Margin.Right - 100, 0);
Scr.ScrollToHorizontalOffset(Scr.HorizontalOffset - 100);
}
}
private void MoveLeft(object sender, RoutedEventArgs e)
{
if (Grid.Margin.Left > 0)
{
Grid.Margin = new Thickness(Grid.Margin.Left - 100, 0, 0, 0);
}
else
{
Grid.Margin = new Thickness(0, 0, Grid.Margin.Right + 100, 0);
Scr.ScrollToHorizontalOffset(Scr.HorizontalOffset + 100);
}
}
}
}
Copy and paste my code in a File -> New -> WPF Application and see the results for yourself.
Eventually, you might want to convert your app to WPF. Since, Winform is condemned to a small death.

Categories

Resources