WPF form must fall down in the task bar.. But I dont know do that?
+-x
x ---> Close the form
- ---> down the form taskbar?
You can use the closing event of the WPF Window to cancel closing and minimize it instead:
XAML:
<Window ... Closing="Window_Closing">
Code behind:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.WindowState = WindowState.Minimized;
}
But you have to be aware that this also prevents other ways of closing the window, e.g. Alt+F4, "Close Window" from the toolbar etc.
You may checkout the WPF NotifyIcon control.
Related
I have a borderless WPF window that I am using this answer to move at the moment: Move a borderless window in wpf
But I would really like to have have a button that when you click and hold lets you drag the window around. Is that possible?
Thank you.
Just attach a PreviewMouseDown event to the Button and use similar code
XAML
<Button PreviewMouseDown="Move" />
or CodeBehind
Button button = new Button();
button.PreviewMouseDown += Move;
Code
private void Move(object sender, RoutedEventArgs e)
{
// "window" is the name of the window
window.DragMove();
e.Handled = true;
}
I have three windows. FirstWindow, SecondWindow and ThirdWindow. FirstWindow has button and click on this button opens the SecondWindow. Analogously, SecondWindow has button and click on this button opens the ThirdWindow. Owner property of the SecondWindow is set as FirstWindow and Owner property of the ThirdWindow is set as SecondWindow. The scenario discribing problem:
Open all windows in a row. It will be looked like this:
Then minimize all windows by click on corresponding icon at top right corner of ThirdWindow.
If you will try to maximize all windows by clicking on FirstLevelWindow or ThirdLevelWinow in taskbar - all will be ok, three windows will be maximized. But if you will click on SecondWindow you will see this:
How can I fix it, or it is just WPF bug? I can give archived expample project if it helps.
UPDATE
Minimize window - click "_" icon, left icon in iconbar of the window. All windows are modal, i.e it opens with ShowDialog() method, not with Show() method. So if you minimize third window - all the windows will be minimized.
Here the code if you don't want download project by link:
FirstWindow XAML:
<Button Click="OpenChildWindow"
Content="ChildWindow"/>
FirstWindow .cs:
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
var window = new SecondLevelWindow();
window.Owner = this;
window.ShowDialog();
}
SecondWindow XAML:
<Button Click="OpenChildWindow"
Content="ChildWindow"/>
SecondWindow .cs:
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
var window = new ThirdLevelWindow();
window.Owner = this;
window.ShowDialog();
}
ThirdWindow is empty window without any content.
Here link to example project
I've just found, that bug is not reproduced if property ResizeMode of ThirdWindow is set to "NoResize". Mb it will be usefull information.
Well, I admit I have no idea what is going on. Did you try to add a fourth window? This become even stranger: the second window bring back the third, but the fourth is still not back.
Anyway, If I had to manage this problem, I would keep a reference of my childWindow in each parent Window. This way on any interesting event (like activate on the second window in your example) I could manage the state of my child as required (WindowState.Normal in your case).
It could be something like that: in xaml of secondWindow:
Activated="SecondLevelWindow_OnActivated"
And then in code behind:
private ThirdLevelWindow _window;
public SecondLevelWindow()
{
InitializeComponent();
}
private void OpenChildWindow(Object sender, RoutedEventArgs e)
{
_window = new ThirdLevelWindow ();
_window.Owner = this;
_window.ShowDialog();
}
public void SecondLevelWindow_OnActivated(object sender, EventArgs e)
{
if (_window != null)
{
_window.WindowState = WindowState.Normal;
}
}
This is a start, but you could also inspect your current state to define the state of your child.
Hope it helps.
I have a UserControl with a number of StackPanel's. I like to hide specific panels depending on the user action. A StackPanel which is visible on startup gives me a number of working buttons. The buttons have click events in the code behind file. After collapsing the panel and then making it visible again the buttons no longer work. Here is a part of my UserControl:
<StackPanel x:Name="buttonPanel" Orientation="Horizontal">
<Button x:Name="ReMindNodeNotes" Content=""
FontFamily="Segoe UI Symbol" FontSize="14" Foreground="#FF292323"
HorizontalAlignment="Left" BorderThickness="1" Padding="0"
UseLayoutRounding="True" Click="NoteClicked" />
<Button x:Name="ReMindNodeRemove" Content=""
FontFamily="Segoe UI Symbol" FontSize="14" Foreground="#FF292323"
HorizontalAlignment="Left" BorderThickness="1" Padding="0"
UseLayoutRounding="True" Click="RemoveClicked" />
</StackPanel>
And here is the code (for now just some text):
private void NoteClicked(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("NoteClicked...");
}
private void RemoveClicked(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("RemoveClicked...");
}
I have been looking for a solution the last two days. No luck so far. Who can help...?
THX Peter
Follow up 1...
Here is the code for collapsing the panel:
private void MoreClicked(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(this.nodeName);
this.buttonPanel.Visibility =
this.buttonPanel.Visibility ==
Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
It works if the buttonPanel has focus. If the focus is on another panel it does not. Furthermore, what I probably should have mentioned... is that users can create multiple instances of the user control.
THX
Follow up 2...
I continue working on a solution of course... ;-) and I found a solution, which however is not the solution I want. Let me explain.
Users can interactively create multiple instances of the user control mentioned before. When a new instance is created, that instance gets focus. Now every instance has its own set of buttons which are on a stackpanel. When the focus goes to another instance I want the panel of the previous instance to collapse. The focus should then be set to the new (or selected existing) instance.
When I do this manually, it works! When I try to achieve this through the GotFocus and LostFocus events however, it does not. Here is the code for the manual solution (which works):
private void MoreClicked(object sender, RoutedEventArgs e)
{
this.buttonPanel.Visibility =
this.buttonPanel.Visibility ==
Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
Here are the LostFocus and GotFocus events:
private void NodeGotFocus(object sender, RoutedEventArgs e)
{
this.buttonPanel.Visibility = Visibility.Visible;
}
private void NodeLostFocus(object sender, RoutedEventArgs e)
{
this.buttonPanel.Visibility = Visibility.Collapsed;
}
I really appreciate your help! THX again...
Thanks for your sample morincer. The problem however is a little more complex. Let me try to explain the solution which I found after some more research. Maybe other developers can benefit from it as well.
I added the GotFocus and LostFocus events to my userconctrol. If I click somewhere inside the usercontrol the focus changes every time. Strange as these events are only defined on the usercontrol itself and not it's children. I have several buttons and a textbox inside the usercontrol and when I for example click on one of the buttons of the usercontrol that has focus the LostFocus and GotFocus events are fired for usercontrol anyway.
The most important event for me in this case is the LostFocus event. When the usercontrol looses focus - for example to another control - I want the button panel to disappear. Since the LostFocus event fires every time a object inside the usercontrol is touched, I cannot distinguish between the situation in which I want to hide and show the buttons.
I got a little closer to a solution by changing the LostFocus event as follows:
private void LostFocus(object sender, RoutedEventArgs e)
{
Object fo = FocusManager.GetFocusedElement();
if (fo.GetType().ToString().Contains("TextBox") ||
fo.GetType().ToString().Contains("ScrollViewer"))
{
this.buttonPanel.Visibility = Visibility.Collapsed;
}
}
This covers most of the situations. When the cursor is positioned in the TextBox the button panel is closed. The button panel is also closed when the user clicks on the background. This seems to be a ScrollViewer (found through debugging the code). Can anyone explain this...?
The situation which is not covered however, is when a user clicks on another usercontrol. It does of course when the user clicks on the TextBox (see the code) but not when the user clicks on a button. I tried to compare sender and FocusManager.GetFocusedElement(). Problem is that the sender returns the usercontrol (which is what I am looking for) but the FocusManager.GetFocusedElement() returns the button that was pressed. Now I could ask for it's parent which is a border then ask for the borders parent which is a stack panel and so on until I arrive at the usercontrol. A code behind file however was introduced with the idea to split design and logic while this solution would tie them together again. If I would change the XAML I would have to change the logic as well. Doesn't seem to be the right solution to me.
I found a solotion by giving every usercontrol a unique name in the constructor. I then give all the buttons unique names as well (I don't use them in my code anyway) starting with the name of the usercontrol. This then gives me the possibility to compare names at runtime and determine whether the focus has changed to another instance of the usercontrol. Here is the code:
private void NodeLostFocus(object sender, RoutedEventArgs e)
{
Object fo = FocusManager.GetFocusedElement();
if (fo.GetType().ToString().Contains("ScrollViewer"))
{
this.buttonPanel.Visibility = Visibility.Collapsed;
}
else if (fo.GetType().ToString().Contains("TextBox"))
{
if (!((TextBox)fo).Name.Contains(this.nodeName))
{
this.buttonPanel.Visibility = Visibility.Collapsed;
}
}
else if (fo.GetType().ToString().Contains("Button"))
{
if (!((Button)fo).Name.Contains(this.nodeName))
{
this.buttonPanel.Visibility = Visibility.Collapsed;
}
}
}
Now this works! But…I don't like the solution. I am depending on names instead of a good architecture. Does anyone hove an idea how to compare the actual sender with the usercontrol that is the parent of the button pressed (FocusManager.GetFocusedElement())? Or any other solution that relies on good programming?
THX again
Can i set a mouselistener (Clicked) in WPF?
Simple,
Just a Click attribute to your xaml control
Assign it a handler
Define the handler in your xaml.cs
In your xaml,
<Button Click="Button_Click"></Button>
In your xaml.cs,
private void Button_Click(object sender, RoutedEventArgs e)
{
//What should be done when you click the control
}
There are loads of mouse events available. Check MSDN for the list of mouse events supported in WPF
If te user clicked where?
If you have a button(or window or pretty much anything else) you simpy add the MouseDown() eventhandler....
I want to disable all default shortcuts in WPF TextBox. Shortcuts like Ctrl + A, Ctrl + V, Ctrl + C etc. Can this be done?. It looks to me that these shortcuts are executed before KeyDown event
You can intercept the keystrokes in the PreviewKeyDown event. Set the e.Handled member to true and that will prevent the actually processing of the keys.
public Window1()
{
InitializeComponent();
CommandManager.AddPreviewCanExecuteHandler(_textBox, _canExecute);
}
private void _canExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = false;
e.Handled = true;
}
The above will prevent the TextBox from saying it can handle any command. You can selectively choose which commands you want to disable by examining the EventArgs. Or you can do this in XAML:
<TextBox x:Name="_textBox">
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" CanExecute="_canExecute"/>
</TextBox.CommandBindings>
</TextBox>
Here we're just disabling the execution of the Copy command. Control-C won't work, nor will the context menu or main menu. In fact, any control that executes the Copy command will be disabled if the focus is in the TextBox.