Maximizing borderless form with multiple monitors c# - c#

I'm currently making a borderless form with a Doubleclick event to maximize form. But I realized that the form wouldn't maximize on the two other screens, only my main middle.
So my code is currently:
private void Form1_DoubleClick(object sender, EventArgs e)
{
if ((this.Height == Screen.PrimaryScreen.WorkingArea.Height) && (this.Width == Screen.PrimaryScreen.WorkingArea.Width))
{
this.Width = 534;
this.Height = 600;
CenterToScreen();
}
else
{
this.Height = Screen.PrimaryScreen.WorkingArea.Height;
this.Width = Screen.PrimaryScreen.WorkingArea.Width;
this.Location = Screen.PrimaryScreen.WorkingArea.Location;
}
}
It might look weird, but I use it to not cover the taskbar.
I need a code like this to dock it to the side, and use it to calculate where the form should be. Looking like this: half right screen dock
when I click one of those 9 buttons, it will dock the screen in different places of the screen. In corner, half of the screen or in the middle.
I tried using a code where the form would detect which screen it was on, and using that again to maximize the form on that screen, but I got a bunch of red lines, and it didn't work in the end.
I have 3 monitors.
Please help.

You hardcoded it to primary screen, which is the screen with the task bar. To allow other screens get the screen the form is currently on an adjust to that.
private void Form1_DoubleClick(object sender, EventArgs e)
{
if ((this.Height == Screen.FromControl(this).WorkingArea.Height) && (this.Width == Screen.FromControl(this).WorkingArea.Width))
{
this.Width = 534;
this.Height = 600;
CenterToScreen();
}
else
{
this.Height = Screen.FromControl(this).WorkingArea.Height;
this.Width = Screen.FromControl(this).WorkingArea.Width;
this.Location = Screen.FromControl(this).WorkingArea.Location;
}
}

Related

How can I prevent my bitmaps from flickering when i release them from dragging?

I am creating my own app in Winforms where I want to be able to create a map and put icons on it. Those icons will reveal information when clicked. The map is a simple image and the icons are bitmaps. The user can drag an icon onto the map, and afterwards drag it again or remove it.
The problem is that when I drag the icon (a bitmap) and release it, it will flicker for a moment. This will happen regardless of the speed, and regardless of wether it is the very first placement of the icon.
My repo for the code: https://github.com/Foxion7/MapMarker
A screenshot of the panels, icons etc.: https://imgur.com/a/pKMJ4lX To the right is the icon you can click to drag a new icon to the map.
I have already tried using Images with transparancy (didnt work for issues unrelated to the flicker), doublebuffering, checking excessive use of Invalidate().
I would also appreciate advice on other ways besides bitmaps and multiple panels to perhaps circumvent the issue, but I've gotten pretty far with this so far.
Below is an excerpt for the 'in-panel' moving of an icon.
// Selecting an existing icon.
private void mapPictureBox_MouseDown(object sender, MouseEventArgs e)
{
Icon selectedIcon = map.CheckCollision(e.Location);
if (selectedIcon != null)
{
SelectIcon(selectedIcon);
currentOffset = new Point((e.X - selectedIcon.center.X) * -1, (e.Y - selectedIcon.center.Y) * -1);
holdingAnIcon = true;
}
}
// Only hides icon on old position when you start dragging to prevent flashing.
private void mapPictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (holdingAnIcon)
{
if(oneTimePerMoveActionsDone)
{
selectedIcon.hidden = true;
mapPictureBox.Invalidate();
oneTimePerMoveActionsDone = false;
}
var dragImage = ResizeImage(selectedIcon.bitmap, iconWidth, iconHeight);
IntPtr icon = dragImage.GetHicon();
Cursor.Current = new Cursor(icon);
}
}
// Releasing after dragging an existing icon.
private void mapPictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (holdingAnIcon)
{
selectedIcon.location = mapPanel.PointToClient(new Point(e.X - (int)(iconWidth / 3.75) + currentOffset.X, e.Y + iconHeight / 5 + currentOffset.Y));
selectedIcon.UpdateCenterPosition();
selectedIcon.hidden = false;
holdingAnIcon = false;
oneTimePerMoveActionsDone = true;
mapPictureBox.Invalidate();
}
}
The flicker (almost always) happens on release of the mousebutton. There is only a very tiny chance the flicker doesn't appear sometimes.

Prevent new window from going offscreen

If the MainWindow is too close to the edge of the screen, opening a New Window with relative positioning can go off screen.
I'd like to have it detect that it's off screen and reposition itself close to the edge, even overlapping the MainWindow. For Top, Bottom, Left and Right.
Example Project Source
https://www.dropbox.com/s/3r2guvssiakcz6f/WindowReposition.zip?dl=0
private Boolean IsWindowOpened = false;
// Info Button
//
private void buttonInfo_Click(object sender, RoutedEventArgs e)
{
MainWindow mainwindow = this;
// Start Info Window
InfoWindow info = new InfoWindow(mainwindow);
// Only Allow 1 Window Instance
if (IsWindowOpened) return;
info.ContentRendered += delegate { IsWindowOpened = true; };
info.Closed += delegate { IsWindowOpened = false; };
// Position Relative to MainWindow
info.Left = mainwindow.Left - 270;
info.Top = mainwindow.Top + 0;
// Open Info Window
info.Show();
}
Example of 1280x720 screen
MainWindow Center Screen
InfoWindow -270px Left, 0px Top
Off Screen
MainWindow Top Left of Screen
InfoWindow -270px Left, 0px Top
Reposition In Screen
MainWindow Top Left of Screen
InfoWindow -160px Left, 0px Top
To Place Dialog to Left
The quick-n-dirty way of doing this is to simply use Math.Max (i.e. the right-most value) to use the offset or 0, whichever is larger. Using System.Windows.Forms.Screen allows us to accommodate for multiple monitors.
private void btnInfoToLeft_Click(object sender, RoutedEventArgs e)
{
// Figure out which screen we're on
var allScreens = Screen.AllScreens.ToList();
var thisScreen = allScreens.SingleOrDefault(s => this.Left >= s.WorkingArea.Left && this.Left < s.WorkingArea.Right);
// Place dialog to left of window, but not past screen border
InfoWindow info= new InfoWindow();
info.Left = Math.Max(this.Left - info.Width - 10, thisScreen.WorkingArea.Left);
info.Top = Math.Max(this.Top - info.Height - 10, thisScreen.WorkingArea.Top);
info.Show();
}
Note that we use the Width of the dialog - it's ActualWidth will be 0 before it is shown on the screen.
To Place Dialog to Right
Similarly, we need to figure out the right-most boundaries of the screen, and account for the width of the main window and dialog, and take the Math.Min value (i.e. the left-most value).
private void btnInfoToRight_Click(object sender, RoutedEventArgs e)
{
// Figure out which screen we're on
var allScreens = Screen.AllScreens.ToList();
var thisScreen = allScreens.SingleOrDefault(s => this.Left >= s.WorkingArea.Left && this.Left < s.WorkingArea.Right);
// Place dialog to right of window, but not past screen border
InfoWindow info = new InfoWindow();
info.Left = Math.Min(this.Left + this.ActualWidth + 10, thisScreen.WorkingArea.Right - info.Width);
info.Top = Math.Min(this.Top + this.ActualHeight + 10, thisScreen.WorkingArea.Bottom - info.Height);
info.Show();
}
This time, we still use the Width of the dialog, but the ActualWidth of the main window, which will be the width after it has been drawn (and possibly resized).
In these examples, I've also placed the dialog above/below the main window. You can set the top of the dialog to be equal to the top of the main window, or play around to get it to line up with the bottom, etc., using this example as a guide.
There are no shortcuts for this kind of problem. You'll have to figure out the dimensions of the screen you're using, then adjust the position of the info window manually.
Take a look at this StackOverflow post: How to get the size of the current screen in WPF?

Prevent Window Boundary from Over Screen Boundary when SizeChange

How to prevent Window Boundary from over Screen Boundary when Window SizeChange in C# WPF?
(that's Restrict Window Boundary in Screen )
Use the Window's OnSizeChanged Event,
and do like this:
//get Screen's Width, Height
private double screenHeight = SystemParameters.FullPrimaryScreenHeight;
private double screenWidth = SystemParameters.FullPrimaryScreenWidth;
private void MultiToolWindow_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
//when window RightBoundary over screen
if (this.Left + this.Width > screenWidth)
this.Width = screenWidth-this.Left; //shrink the width
//when window DownBoundary over screen
if (this.Top + this.Height > screenHeight)
this.Height = screenHeight-this.Top; //shrink the height
}
Note that when using this, Window's SizeToContent Property should be in Manual,
if not,
you can change it like this:
public void SomeMethod(){
//set to manual, this will invoke OnSizeChangedEvent at the same time but the shrink code won't work
this.SizeToContent = SizeToContent.Manual;
//this will invoke OnSizeChangedEvent and because now is manual the shrink code works
this.SizeToContent = SizeToContent.Manual;
}
do twice to ensure when window's original SizeToContent State is WidthAndHeight can take effect too,
first time will set it to Manual and the shrink code won't take effect,
and second time cause the state is manual so the shrink code will take effect.

Setting the location of WPF window dynamically when we change the screen resolution from low to high

When we change screen resolution the WPF window not showing on proper location(Bottom Right).
1.Change screen resolution from high to lower value.
2.Open the WPF window.
3.Again change screen resolution from low to high.
The window will not display on proper location it is going Up .
I want it to again at bottom right.
How can I fix this problem?
You will have to move the window after resolution change using your own code I believe, something like this:
window.Left = SystemParameters.PrimaryScreenWidth - window.Width;
window.Top = = SystemParameters.PrimaryScreenHeight - window.Height;
Check this post to see, how to detect screen resolution change
http://social.msdn.microsoft.com/Forums/en-US/fc2f6dfa-f22c-477e-b3a5-54a088176932/detecting-screen-resolution-change
So the whole code would be like this:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
this.Top = SystemParameters.PrimaryScreenHeight - this.Height;
}
}

User Drawn Controls: the MSN chat window

I'm wondering about the famous MSN chat clients conversation windows! I'm sure there must be a lot of different aspects but I'd like to focus on those little sliding panes. For instance where the pictures of the people in the conversation are displayed. When you click the collapse button the pictures disappear and the panel gracefully slides in, and when you click it again to expand, it slides out and the pictures are smoothly faded in.
How would one go about customly drawing a control in WinForms that had similar behaviour?
This should give you an idea how animate your width.
int _collapsedWidth;
int _fullWidth;
float _speed;
float _acurateWidth;
System.Diagnostics.Stopwatch _stopwatch = new Stopwatch ();
int _animationDirection;
AnimatedControl (){
Application.Idle += ApplicationIdle;
}
void Expand (){
_animationDirection = 1;
_stopwatch.Start();
}
void ApplicationIdle (object sender, EventArgs e){
if (_animation.Direction == 0)
return;
float delta = _stopwatch.Elapsed.TotalMilliseconds * _speed;
_acurateWidth += delta;
if (_acurateWidth < _collapsedWidth)
{
_animationDirection = 0;
_acurateWidth = _collapsedWidth;
_stopwatch.Stop();
}
else if (_acurateWidth > _fullWidth)
{
_animationDirection = 0;
_acurateWidth = _fullWidth;
_stopwatch.Stop();
}
_stopwatch.Reset();
this.Width = (int)System.Math.Round(_acurateWidth , MidpointRounding.AwayFromZero);
this.Invalidate (); // May not need this
}
and for the pictures, somthing similar but using translucent images, you might want to make a new control with a transparent background color for them as well depending how you want to paint things.
You can then put this control into one of the LayoutPanel controls to move your other controls around in the form to match the width.

Categories