WPF change main window opacity only while secod window is close - c#

i have a WPF application with main window and second window that opened from main window button. i want the main window opacity to change while second window is open and when i will close it the opacity of the main window will back to defaut.

This is your first window's code to invoke the second window.
var newWindow = new Window1();
newWindow.ShowDialog();
You can add an event handler to newWindow to detect Window1's close.
var newWindow = new Window1();
Application.Current.MainWindow.Opacity = 0.5;
newWindow.Closed += (sender, e) =>
{
Application.Current.MainWindow.Opacity = 1;
};
newWindow.ShowDialog();

got it....
private void Window_Closed(object sender, EventArgs e)
{
Application.Current.MainWindow.Opacity = 1;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Opacity = 1;
}

Related

Cannot show MainWindow after minimization

I try to avoid the XY Problem by saying immediately what I want and then what I get. 😛
So, first of all, I minimize my MainWindow and thoroguh its NotifyIcon ContextMenu I want that my MainWindow reappears.
The problem: the MainWindow doesn't appear/show as Window, but it appears as Icon in the toolbar (see figure 2).
The code:
This is the TrayIcon initializer:
private void InitializeTrayIcon()
{
KyactusTrayIcon = new NotifyIcon();
KyactusTrayIcon.Icon = AppIcon;
KyactusTrayIcon.Visible = true;
KyactusTrayIcon.ContextMenu = new ContextMenu(new []
{
new MenuItem("Chiudi", ExitApplication),
new MenuItem("Mostra", ShowMainWindow),
});
ShowNotification(#"Ciao " + Globals.CurrentUser.Name + #"!", #"Benvenuto su Kyactus");
}
This is the delegate responsible to show the minimized MainWindow (not working at all):
private void ShowMainWindow(object sender, EventArgs e)
{
WindowState = WindowState.Normal;
Topmost = true;
Show();
Activate();
}
This is what happens when the MainWindow is minimized by clicking the [-] button (ie the Hide() method):
private void MainWindow_OnStateChanged(object sender, EventArgs e)
{
switch (this.WindowState)
{
case WindowState.Maximized:
ShowNotification("Bleah!", "Questo è proprio brutto! :(");
break;
case WindowState.Minimized:
Hide();
ShowNotification("Avviso", "L'applicazione è ora minimizzata qui");
break;
case WindowState.Normal:
break;
}
}
Step one. The method MainWindow_OnStateChanged will be invoked when click on [-]:
Step two. The window disappears (ok) and the Tray icon appears (ok). Then I click on 'Mostra' (translated as 'Show') and the ShowMainWindow delegate will be invoked
Step three. This is the final step, that is, what I do not expect. The MainWindos 'lives' as an Icon in the toolbar. But I can't see it as a Window.
Please note that I have not this problem when I close the window by clicking [X] instead of [-]. So, my suspect is the MainWindow's Window.State. I tried to restore it implementing the WindowState.Normal into the ShowMainWindow, but nothing.
Update: if is use WindowState.Maximized in the ShowMainWindow method,
I can see the window again, but it is maximized and this is bad and ugly.
Just change the order of operation when showing the window
private void ShowMainWindow(object sender, EventArgs e)
{
Show();
WindowState = WindowState.Normal;
Topmost = true;
Activate();
}
Simply,create some class-level integer variables and store the height,width and positioning values there.Then use them to get back the size of your window :
int height;
int width;
double left;
double top;
private void MainWindow_SizeChanged
{
height = this.Height;
width = this.Widthl
left = this.Left;
top = this.Top;
}
private void ShowMainWindow(object sender, EventArgs e)
{
this.Height = height;
this.Width = width;
this.Left = left;
this.Top = top;
}

ShowDialog method without blocking other windows in WPF

I write program for sorting music.
For saving your time and better understanding of my issue,i will write short.
Here is my problem.
I have some cycle in MainMethod.
Here is cycle
private void OkButton(object sender, RoutedEventArgs e)//when i press ok button in Main window i run cycle
{
for (int i = 0; i < 50; i++)
{
//do something.
Window window1 = new Window();
window1.ShowDialog();//if i use ShowDialog it blocks MainWindow.
//window1.Show();if i use Show it continues creating new windows. in cycle.
}
}
So i need to delay executing MainWindow OkButton method,while window1 is opened.Without blocking Main Window.
You can use async/await and a semaphore along these lines:
private async void Button_Click(object sender, RoutedEventArgs e)
{
var signal = new SemaphoreSlim(0, 1);
for (int i = 0; i < 10; i++)
{
var window = new Window();
window.Closed += (s, _) => signal.Release();
window.Show();
await signal.WaitAsync();
}
}

Double Click on label open Form C#

Im trying to open a new form when a label is double clicked. Im able to drag and drop the label .Im trying to open a new form on double click of label now.
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
private void control_DoubleClick(object sender, EventArgs e)
{
frm = new Frm();
frm.ShowDialog();
frm.Dispose();
}
EDIT 1:
I have tried both possible answers below, and they have not worked for me?
A more cleaner way is (note I changed Frm to Form1):
private void control_DoubleClick(object sender, EventArgs e)
{
using (Form1 frm = new Form1())
{
frm.ShowDialog();
}
}
You can't add DragDrop on MouseDown and then DoubleClick. That won't work.
I don't think there's an easy way to get around that, but once a control is being dragged, it won't respond to double click messages.
I've made some quick tests, and there's a "hacky" way. It'll make your dragging look weird (since it'll start after some time, instead of immediately after you press the mouse button), but here it goes:
private bool _willDrag = false;
private bool control_MouseUp(object sender, MouseEventArgs e)
{
// disable dragging if we release the mouse button
_willDrag = false;
}
private bool control_DoubleClick(object sender, EventArgs e)
{
// disable dragging also if we double-click
_willDrag = false;
// .. the rest of your doubleclick event ...
}
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
if (control == null)
return;
_willDrag = true;
var t = new System.Threading.Timer(s =>
{
var callingControl = s as Control;
if (callingControl == null)
return;
// if we released the mouse button or double-clicked, don't drag
if(!_willDrag)
return;
_willDrag = false;
Action x = () => DoDragDrop(callingControl.Name, DragDropEffects.Move);
if (control.InvokeRequired)
control.Invoke(x);
else
x();
}, control, SystemInformation.DoubleClickTime, Timeout.Infinite);
}
In the form.Designer right click on your label then properties, in the properties window click in events (the thunder icon), in the double_Click event dropdown select the event handler (control_DoubleClick) this method must have two parameters an object and a eventArgs
This is tricky as the DoDragDrop will eat up any further mouse events, and MSDN posting a rather stupid example doesn't help much.
Solution: Do not start the D&D in the MouseDown if you want to still receive click or double click events but use the MouseMove instead:
Replace this
private void control_MouseDown(object sender, MouseEventArgs e)
{
var control = sender as Control;
this.DoDragDrop(control.Name, DragDropEffects.Move);
}
by this:
private void control_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
DoDragDrop((sender as Control), DragDropEffects.Move);
}
Don't forget to hook up the new event!

MouseLeave detection not working with ImageForm

I've got a smaller image in my form. When the user hovers over the image it brings up a larger view of the image (that follows the mouse, but stays a certain distance from the mouse). In order to do this I am generating a Form with no FormBorderStyles when the cursor hovers the image.
The problem I'm running into is that the first form doesn't seem to detect any longer that the mouse is hovering or leaving the PictureBox once the form activates. The Form also doesn't follow the cursor.
Here is the slimmed down version of what I've got:
C#
bool formOpen = false;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseHover += pictureBox1_MouseHover;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
}
void pictureBox1_MouseHover(object sender, EventArgs e)
{
if (formOpen == false)
{
Form form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
form.BackColor = Color.Orchid;
//Show the form
form.Show();
form.Name = "imageForm";
this.AddOwnedForm(form);
//Set event handler for when the mouse leaves the image area.
//form.MouseLeave += form_MouseLeave;
//Set the location of the form and size
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
this.TopMost = true;
formOpen = true;
form.Location = new Point(Cursor.Position.X, Cursor.Position.Y);
}
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
//MessageBox.Show("Worked");
}
}
The MouseLeave (and other events) was not recognized because the opening of the popup window and especially making it topmost=true took away the focus from the original form and its PictureBox.
It also didn't move because not code for moving was provided..
Here are a few changes that will make the form move:
You need a reference to it at the form1 level
you need to move it in the MouseMove event
Note that Hover is a once-only type of event. It fires only once until you leave the control.. (Note: Setsu has switched from Hover to Enter. This works fine, but lacks the short delay before showing the 2nd Form. If you want that back you can either switch back to Hover or you can fake the hover delay by a Timer, which is what I often do.)
// class level variable
Form form;
private void Form1_Load(object sender, EventArgs e)
{
pictureBox1.MouseEnter += pictureBox1_MouseEnter;
pictureBox1.MouseLeave +=pictureBox1_MouseLeave;
pictureBox1.MouseMove += pictureBox1_MouseMove; // here we move the form..
}
// .. with a little offset. The exact numbers depend on the cursor shape
void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if ((form != null) && form.Visible)
{
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
}
}
void pictureBox1_MouseEnter(object sender, EventArgs e)
{
// we create it only once. Could also be done at startup!
if (form == null)
{
form = new Form();
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
//form.BackColor = Color.Orchid;
form.Name = "imageForm";
this.AddOwnedForm(form);
form.BackColor = Color.Black;
form.Dock = DockStyle.Fill;
form.Size = new Size(30, 30);
form.BackgroundImageLayout = ImageLayout.Center;
//this.TopMost = true; // wrong! this will steal the focus!!
form.ShowInTaskbar = false;
}
// later we only show and update it..
form.Show();
form.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5);
// we want the Focus to be on the main form!
Focus();
}
private void pictureBox1_MouseLeave(object sender, EventArgs e)
{
if (form!= null) form.Hide();
}
MouseHover = Occurs when the mouse pointer rests on the control. (msdn)
Try MouseMove instead.

Open childform in upper right corner of mainform

I am trying to open a (non decorated) childform at the upper right corner of my main form no matter if the main form is maximized or at it's normal size.
But no matter how I try I don't get it to open where I want it to.
I found a post that described how to open the form relative to another control in the form, but that didn't work either:
How to display a Modal form in a position relative to the a control in the parent window (opener)
Have tried to search for a few hours now on google for a solution, but either there's no answer (doubdfull) or I am not searching for the tight words combination (more likely).
Could anyone please either point me to a similar question, or help me how to achieve what I am hoping for?
Sounds to me you ought to be using a UserControl that you anchor to the top and right. But let's make a form work. You'll need to wire its Load event so you can move it into the right spot after it rescaled itself. Then you need the main form's LocationChanged and Resize events so you can keep the child form in the right spot.
So a sample program with boilerplate Form1 and Form2 names and a button on Form1 to display the child could look like this:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
this.button1.Click += button1_Click;
this.Resize += this.Form1_Resize;
this.LocationChanged += this.Form1_LocationChanged;
}
Form child;
private void button1_Click(object sender, EventArgs e) {
if (child != null) return;
child = new Form2();
child.FormClosed += child_FormClosed;
child.Load += child_Load;
child.Show(this);
}
void child_FormClosed(object sender, FormClosedEventArgs e) {
child.FormClosed -= child_FormClosed;
child.Load -= child_Load;
child = null;
}
void child_Load(object sender, EventArgs e) {
moveChild();
}
void moveChild() {
child.Location = this.PointToScreen(new Point(this.ClientSize.Width - child.Width, 0));
}
private void Form1_Resize(object sender, EventArgs e) {
if (child != null) moveChild();
}
private void Form1_LocationChanged(object sender, EventArgs e) {
if (child != null) moveChild();
}
}
Try something like that:
private void button1_Click(object sender, EventArgs e)
{
ChildForm win = new ChildForm();
int screenHeight = Screen.PrimaryScreen.WorkingArea.Height;
int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
Point parentPoint = this.Location;
int parentHeight = this.Height;
int parentWidth = this.Width;
int childHeight = win.Height;
int childWidth = win.Width;
int resultX = 0;
int resultY = 0;
if ((parentPoint.X + parentWidth + childWidth) > screenWidth)
{
resultY = parentPoint.Y;
resultX = parentPoint.X - childWidth;
}
else
{
resultY = parentPoint.Y;
resultX = parentPoint.X + parentWidth;
}
win.StartPosition = FormStartPosition.Manual;
win.Location = new Point(resultX, resultY);
win.Show();
}
I think you should try something like this:
private void buttonOpen_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Show();
//"this" is the parent form
frm2.DesktopLocation = new Point(this.DesktopLocation.X + this.Width - frm2.Width, this.DesktopLocation.Y);
}
Simple, easy, and works (for me).

Categories

Resources