SplitView.PaneClosed event is available but not for PaneOpened - c#

According to the https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.splitview.paneclosed.aspx there is no PaneOpened event for the SplitView control, only PaneClosed event for the SplitView control that exists.
I have a Button control inside a SplitView pane that needs to change in size according whether the pane is opened or closed. So my plan is I will place a piece of code that will change the button size wider in the PaneOpened event, and restore it back to the small size in PaneClosed event. But it seems there is no PaneOpened event.
Any other way that I can achieve this?

Thanks to the new RegisterPropertyChangedCallback in UWP, you can now monitor property change events of any DependencyProperty, including native ones.
public SplitViewPage()
{
this.InitializeComponent();
this.splitView.RegisterPropertyChangedCallback(SplitView.IsPaneOpenProperty, IsPaneOpenPropertyChanged);
}
private void IsPaneOpenPropertyChanged(DependencyObject sender, DependencyProperty dp)
{
// put your logic here
}

Related

C# Winform panel Shown event

Is there an event for panel that is equivalent to form event Shown?
I had a few couple of panel switching within a form which will never be closed.
However i couldn't find anything close to an event like Shown which is used in form.
The closes i had is Paint event. However i only wish to update the panel once every time it is shown.
Form.Shown is not raised every time the form is shown, rather it Occurs whenever the form is first displayed. This being said, there is no Panel.Shown event, and no event which is raised "whenever a panel is first displayed".
You can simulate this behavior with the Panel.Paint event, using a flag to keep track of whether it's been "shown" once before. This will make it behave similar to Form.Shown.
private bool panel1Painted = false;
private void panel1_Paint(object sender, PaintEventArgs e)
{
if (!panel1Painted)
{
// do your shown stuff here
panel1Painted = true;
}
}
To keep in the spirit of Form.Shown, you may want to reset the flag if the Panel is reconstructed. This is not the same as shown.
You could listen on the VisibleChanged event and only act on when visibility = true.
https://msdn.microsoft.com/en-us/library/system.windows.forms.panel_events%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
You could also experiment with the Enter and Invalidated events to see if these give you the results you want.
Or if disabling the panel when leaving it is an option, you might be able to use the EnabledChanged event in your toolbox.

Capture KeyDown when event does not reach my control

First: I know that there are literally thousands of answers like: "Add a handler to Keyboard.KeyDownEvent and have fun!". But in my situation this does not work.
I have a custom control CustomControl which derives from Canvas but has no Children. Instead it draws its "children" directly to the DrawingContext in the OnRender. My Control is HitTestVisible, it is tab stop but is not focusable. It is often reused and sometimes in a ScrollViewer.
This CustomControl has a custom implementation for selecting something like text, and should copy that selected text to the ClipBoard on Ctrl+C.
To do this, I added a handler in the constructor:
public CustomControl()
{
//// ... other stuff
AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)CopyMarkedNucleotidesToClipboard);
}
And here is the Problem: When my control is inside a ScrollViewer, and I hit Ctrl+C, the KeyDownEvent is raised on the ScrollViewer and bubbles up to the window, and therefore never reaches my Control.
What can I do inside my CustomControl to capture every Ctrl+C in the window where it resides?
PS: I already set IsTabStop="False" and Focusable="False". But then the next sibling of the ScrollViewer would raise the event which would still bubble up to the window. And I don't want to go through all controls which are higher in the visual tree and set IsTabStop="False" and Focusable="False" which would be wrong...
I already found this article http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx but I think, that there must be a more wpf-like way!
The suggestion of Sinatr was correct! Thanks!
The solution is to find the parent window in the load and subsribe to his KeyDownEvent.
public CustonControl()
{
Loaded += HookToCtrlC;
}
private void HookToCtrlC(object sender, EventArgs e)
{
var parentWindow = Window.GetWindow(this);
parentWindow.KeyDown += CopySelectedTextToClipboard;
}
private void CopyMarkedNucleotidesToClipboard(object sender, KeyEventArgs e)
{
Clipboard.SetText("Hello World!");
}

WP8.1 AppBar size change

How do I monitor AppBar's size changes? Specifically, I want to know when it gets opened(to show secondary commands and labels underneath icons).
There is a SizeChanged event, but it fires only before AppBar is shown on the screen.
CommandBar has Opened and Closed events. They are fired when SecondayCommands are shown/hidden.
Note that those events will be fired only if you have SecondayCommands in your AppBar.
As I've checked - Opening/Closing your AppBar doesn't change its ActualHeight. If you want to see its size changing you can play with ClosedDisplayMode - for example put this code in your AppBarButton.Click:
private void AppBarToggleButton_Click(object sender, RoutedEventArgs e)
{
Debug.WriteLine(BottomAppBar.ActualHeight.ToString());
if (BottomAppBar.ClosedDisplayMode == AppBarClosedDisplayMode.Compact)
BottomAppBar.ClosedDisplayMode = AppBarClosedDisplayMode.Minimal;
else BottomAppBar.ClosedDisplayMode = AppBarClosedDisplayMode.Compact;
}
The code above changes ActualHeight and thus SizeChanged event is being fired.

How to draw favicon of a website on tabcontrol

I am able to draw a close button on tab using e.Graphics.Drawimage in OnDrawItem event of TabControl but i want to display the favicon of the website on that tab after the DocumentCompleted event of webbrowser control but i cannot use e.Graphics.Drawimage in DocumentCompleted event.
Is there an alternative way to do this.
Thanks for your help.
OnDrawItem is the correct way. If you do it any other way, your icon will be erased the next time the tab needs to be redrawn (e.g. if you switch to a different tab, or minimize and then restore the window). In WinForms, you should only draw a control from that control's draw events.
What you need to do is, in your DocumentCompleted event, save off the icon (e.g. in a field on your UserControl or Form class), and then call Invalidate on the tab control. That will result in your OnDrawItem event getting fired. Your OnDrawItem can then draw the icon, as long as the field has been assigned. Something roughly like this:
private Image _favicon;
private void WebBrowser1_DocumentCompleted(...) {
_favicon = ...get the icon...;
TabControl1.Invalidate();
}
private void TabControl1_OnDrawItem(...) {
if (_favicon != null)
e.Graphcs.DrawImage(_favicon, ...);
}

How to capture mouse wheel on panel?

How to capture mouse wheel on panel in C#?
I'm using WinForms
EDIT:
I try to do it on PictureBox now.
My code:
this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Click");
}
Clicking works. Wheelling doesn't.
Why?
If you can't see the "MouseWheel" event on a component, then you need to create it manually. Also, we need to focus that component, otherwise the "MouseWheel" event will not work for that component. I will show you how to create a "MouseWheel" event for "pictureBox1" and how it works.
INSIDE THE CONSTRUCTOR, create a mousewheel event on that component.
InitializeComponent();
this.pictureBox1.MouseWheel += pictureBox1_MouseWheel;
CREATE THE FUNCTION manually. According to my example, call it "pictureBox1_MouseWheel"
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
//you can do anything here
}
CREATE a MouseHover event on that component (Go to properties in PicureBox1, select event, locate "MouseHover" and double-click the "MouseHover" event).
CALL "Focus()"; method inside that MouseHover event.
pictureBox1.Focus();
Now run the program.
Windows sends the WM_MOUSEWHEEL message to the control that has the focus. That won't be Panel, it is not a control that can get the focus. As soon as you put a control on the panel, say a button, then the button gets the focus and the message.
The button however has no use for the message, it's got nothing to scroll. Windows notices this and sends the message to the parent. That's the panel, now it will scroll.
You'll find code for a custom panel that can get the focus in this answer.
UPDATE: note that this behavior has changed in Windows 10. The new "Scroll inactive windows when I hover over them" option is turned on by default. The makes the mouse wheel behavior more consistent with the way it works in a browser or, say, an Office program. In this specific case the picturebox now will get the event. Watch out for this.
To wire it up manually...
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
private void panel1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
///process mouse event
}
Easier method is in visual studio click on panel, goto properties viewpanel, select events, locate and double click the "mousewheel" event.
In Winforms, this is achieved using the Control.MouseWheel event
Getting mousewheel events is tricky. The easiest way is using
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
instead of
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
This way the form gets the event instead of control. This way is easy but has one problem: you can use only one mousewheel event in your form.
If you have more than one control to get mousewheel event the best way is This answer by "Shehan Silva - weltZ"

Categories