Panel not getting focus
The Panel class was designed as container, it avoids taking the focus so a child control will always get it. You'll need some surgery to fix that. I threw in the code to get cursor key strokes in the KeyDown event as well:
using System;
using System.Drawing;
using System.Windows.Forms;
class SelectablePanel : Panel {
public SelectablePanel() {
this.SetStyle(ControlStyles.Selectable, true);
this.TabStop = true;
}
protected override void OnMouseDown(MouseEventArgs e) {
this.Focus();
base.OnMouseDown(e);
}
protected override bool IsInputKey(Keys keyData) {
if (keyData == Keys.Up || keyData == Keys.Down) return true;
if (keyData == Keys.Left || keyData == Keys.Right) return true;
return base.IsInputKey(keyData);
}
protected override void OnEnter(EventArgs e) {
this.Invalidate();
base.OnEnter(e);
}
protected override void OnLeave(EventArgs e) {
this.Invalidate();
base.OnLeave(e);
}
protected override void OnPaint(PaintEventArgs pe) {
base.OnPaint(pe);
if (this.Focused) {
var rc = this.ClientRectangle;
rc.Inflate(-2, -2);
ControlPaint.DrawFocusRectangle(pe.Graphics, rc);
}
}
}
NSOpenPanel cannot get focus
In this context (app without a window) you need to set the NSApplication activation policy to .accessory
to activate the panel (there's also .regular
but it would show a Dock icon and a menu bar).
import AppKit
NSApplication.shared.setActivationPolicy(.accessory)
let dialog = NSOpenPanel()
dialog.title = "Choose a .tif file or a folder"
dialog.showsResizeIndicator = true
dialog.showsHiddenFiles = false
dialog.canChooseDirectories = true
dialog.canCreateDirectories = true
dialog.allowsMultipleSelection = false
dialog.allowedFileTypes = ["tif", "tiff"]
dialog.isFloatingPanel = true
if (dialog.runModal() == NSApplication.ModalResponse.OK)
{
let result = dialog.url // Pathname of the file
if (result != nil)
{
let path = result!.path
print(path)
exit(0)
}
}
exit(1)
Event to know if Panel lost focus in Winforms application?
I'm thinking LostFocus
is what you're looking for.
Edit
As another strategy, you know that calling panel.BringToFront
will queue an update in your UI. Wherever you are calling panel.BringToFront
, perhaps you could just call one of your own methods, or trigger one of your own events. This way, you know when the event will be triggered, and exactly what will trigger it.
The reason I thought of this is that I doubt your Panel
will ever actually have the focus itself - rather, one of its child controls will likely have the focus. By doing you own event trigger, you don't have to rely on something as volatile as focus. Plus, even if the Panel
did have the focus, it's always possible that it could lose focus in other ways than your own panel switching.
Edit #2
Here's an attempt at a quick implementation of my previous ramblings. I'll be making the assumption that this code be placed somewhere in the same class as all your Panel
instances (i.e. in your Form
class).
// This will be the custom event to which you can subscribe
// in order to detect a switch in panels.
public event EventHandler PanelSwapEvent;
// This reference the currently visible panel - should be set
// to the default panel in the form's constructor, if possible.
private Panel currentPanel;
// This actually switches the panels, to minimize code duplication.
private void switchToPanel(Panel p)
{
Panel lastPanel = currentPanel;
currentPanel = p;
// Move the panels, and invoke the event.
p.BringToFront();
if(PanelSwapEvent != null)
PanelSwapEvent(lastPanel, new EventArgs());
}
// Here's the actual event handler (replaces your
// pnlServiceInfo_LostFocus handler).
private void PanelSwapHandler(object sender, EventArgs e)
{
// whatever you want to do when panels are swapped
}
In this example, the sender
of the event handler is the panel that lost "focus". Using it is as simple as saying switchToPanel(pnl_whatever)
to indicate that you would like to switch from the current panel to the panel named pnl_whatever
.
How to force a focus on a control in windows forms
Ok, finally found the answer:
As I said my textbox is inside user control which is inside panel which is inside a form.
When I need my user control I add it to panel. To get focus on my textbox I have to firstly focus my user control so something like this:
In my top Form:
panel.Controls.Add(myUserControl);
myUserControl.Focus();
and then in my user control:
myTextBox.Select();
Note that if I used: myTextBox.Focus() it wouldn't work (don't know why). Also if I used myUserControl.Select() instead of myUserControl.Focus() it wouldn't work either.
This seems to be the only combination which works.
Related Topics
Fluent and Query Expression - Is There Any Benefit(S) of One Over Other
C# Data Connections Best Practice
How to Remove Duplicates from a C# Array
What's the Strangest Corner Case You'Ve Seen in C# or .Net
Raw SQL Query Without Dbset - Entity Framework Core
Difference Between Null and System.Dbnull.Value
Why Is There No Foreach Extension Method on Ienumerable
C# Getting the Path of %Appdata%
Linq-To-Entities Join VS Groupjoin
Will Using 'Var' Affect Performance
Desktop Applicaton Not Opening After Installation in Client System
Use a Variable from Another Method in C#
What Are Automatic Properties in C# and What Is Their Purpose
How to Modify a CSS Style in the Code Behind File for Divs in ASP.NET