RoutedEventHandler not properly added to the specified elements - c#

I'm trying to add RoutedEventHandler to all the TextBoxes through code, using the following line of code:
this.AddHandler(TextBox.GotFocusEvent, new RoutedEventHandler(textBox_GotFocus));
The code above binds the handler to all the form control on the Window instead of TextBoxes alone. Please can someone
explain why this happens
and how to do it right.
Thank you.

Probably not exactly what you are after because it will still fire on every UIElement. But, you can do the following to get the "end result" you need.
public void textBox_GotFocus(object sender, RoutedEventArgs e)
{
var textBox = e.Source as TextBox;
if (textBox == null)
return;
//what ever you wanted to do
}

Related

Selection of all of the content of TextBox is not working as expected in WPF

Im having troubles with Selecting All content inside of a TextBox.
Ussually by pressing enter I'm jumping from one textbox to another, because there are like 6-7 TextBoxes below each other
in my Grid, and by pressing enter I need to jump from one to another,
private void Grid_PreviewKeyDown_1(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
UIElement element = e.Source as UIElement;
element.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
//TextBox tb = (sender as TextBox);
//if (tb != null)
//{
// tb.SelectAll();
//}
}
}
And while I'm on some of them when I press Enter I'm doing some calculation like this:
private void txt2_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
try
{
CalculateSomethingFromOtherTextBoxes();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
My Question is next: When I jump from each other and when I finish calculation (enter is pressed), the next TextBox I will jump to I would like SELECTALL of TextBox's content when I jumped on it.
In case I want to edit some value or whatever, and it is confusing sometimes content insidee is selected and sometimes it is not.
I tried setting GotFocus event on each of TextBoxes and It looks like this:
private void txt3_GotFocus(object sender, RoutedEventArgs e)
{
txt3.SelectAll();
}
But unfortunately somehow this is sometimes working sometimes it is not, I mean all of content is selected sometimes and sometimes it is not..
Thanks guys
Cheers
Try to handle the GotKeyboardFocus event instead of the GotFocus event. This should work:
private void txt3_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
txt3.SelectAll();
}
There is no property that you can set to select all of the Text in a TextBlock or TextBox. Selecting all text must be accomplished using the TextBoxBase.SelectAll Method. What you could do in a Style is to set an event handler for the GotFocus event, where the handler code would call SelectAll, but your handler would of course need to be in code and not XAML.
One other possibility would be for you to create an Attached Property that would select the text whenever the TextBox gets focus, but again it's not possible to do this in XAML.

How do I get the UIElement that triggered a MouseDoubleClick Event?

I'm working on a simple IM program as a personal project, and I've hit a bit of a snag. It's really more of a cosmetic thing, but I'm having some trouble with it. I've got a sidebar that lists all of a user's contents in the main window, and I'd like to set it up so that when a user clicks on a contact name, a tab opens in the chat area of the main window with a chat session opened with that contact. The really important part of this is for me to be able to get the UIElement, in this case a Label, that kicked off the MouseDoubleClick event. Once I can access this, I can access the information that I need to make the connection. Unfortunately, I'm a bit rusty with mouse events, and can't figure out how to get back to the Label once the event has been fired. My source code for programmatically creating the label is as follows:
foreach (ContactInfo contact in ContactList)
{
Label currentContact = new Label();
currentContact.Content = contact.ContactName.ToString() + " (" + contact.MachineName.ToString() + ")";
currentContact.MouseDoubleClick += new MouseButtonEventHandler(ContactDoubleClickHandler);
StckPnl_Contacts.Children.Add(currentContact);
}
And the (currently empty) handler is this:
public void ContactDoubleClickHandler(object sender, MouseButtonEventArgs e)
{
}
Am I going about this the wrong way? Any help would be appreciated.
You can inspect the sender (first casting it to the type) to get the element that triggered the event:
Label targetLabel = sender as Label;
if (targetLabel != null)
{
// Do something. I recommend not doing a direct cast in case someone in the future hooks another control type to the event handler.
}
You can use either of following to access the sender details
public void ContactDoubleClickHandler(object sender, MouseButtonEventArgs e)
{
var uiElement = (UIElement) sender; // cast it to UIElement
}
public void ContactDoubleClickHandler(object sender, MouseButtonEventArgs e)
{
var dp = (DependencyObject) sender; // cast it to dependency object.
}
Actually, the sender is your Label, you just have to transform it using:
Label contact = sender as Label;
Be sure to check if contact is null though, before performing any further operations.

Recognizing sender button control in click event

I made a custom button that has a field named Data.
I add this button programatically during runtime to my winform and on adding I also define a click event for them. Well, Actually I only have one method and I subscribe the newly added buttons to this method.
But in the click event I want to access this Data field and show it as a message box, but it seems that my casting is not right:
CustomButton_Click(object sender, EventArgs e)
{
Button button;
if (sender is Button)
{
button = sender as Button;
}
//How to access "Data" field in the sender button?
//button.Data is not compiling!
}
UPDATE:
I am sorry, I ment with "is not compiling" that .Data does not show up in intelisense...
You need to cast to the type of your custom class that has the Data field.
Something like:
YourCustomButton button = sender as YourCustomButton;
Assuming your custom button type is CustomButton, you should do this instead:
CustomButton_Click(object sender, EventArgs e){
CustomButton button = sender as CustomButton;
if (button != null){
// Use your button here
}
}
If you dont want to set a variable the simple way to do is:
((CustomButton)sender).Click
or whatever you want.
I found a funny check assignment in a win forms project on Github:
private void btn_Click(object sender, EventArgs e){
// here it checks if sender is button and make the assignment, all in one shot.
// Bad readability, thus not recommended
if (!(sender is Button senderButton))
return;
var _text = senderButton.Text;
...

How can I keep multiple controls in focus?

I have a tree view on the left side. Selecting a node displays relevant information in a form on the right side.
Would I be able to keep the tree and any one control (textbox, combobox, checkbox) on the right in focus at the same time? This will enable a user to select a field, make a change, select another node, and without having to go back and select the same field again, just type and change the value of the same field.
Thanx.
EDIT
I suppose one could implement such behaviour manually:
private Control __cFocus;
private void {anyControl}_Focus(object sender, EventArgs e)
{
__cFocus = (Control)sender;
}
private void treeView1_AfterSelect(object sender, EventArgs e)
{
__cFocus.Focus();
}
I was just wondering if there exists an automatic / more elegant solution
EDIT 2
Ok, so it seems I'll have to implement it manually. Manual implementation it is then. However, now there seem to be another problem; not sure if I should ask this as a separate question.
When selecting a node the textbox gains focus as intended, but only when using the keyboard. It doesn't work when selecting a node with the mouse. First I thought that it might be a mouse event that's interfering, but stepping revealed that the MouseUp event fired first and then the AfterSelect event which sets the focus, so I don't think it's interfering. The textbox's Enter event is also fired, but for some reason it loses focus again to the tree.
Thanx
no, you cannot keep two controls in focus at the same time. But what you can do is set the focus to the target control in the treeview AfterSelect event
private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
textBox1.Focus();
textBox1.SelectAll();
}
then in your textbox leave, save the changes, like so:
private void textBox1_Leave(object sender, EventArgs e)
{
//save changes here
}
this way, everytime you select an item in the treeview, check your textbox for change and save as needed, then you will refocus on the textbox for your next edit
There only can be one element having the focus!
But I have an idea for you that might solve your problem. Assuming you have a window with a TreeView and a TextBox. Set the HideSelection property of the TreeView to false and subscribe the AfterSelect event (like edeperson already answered) like this:
private void OnTreeViewAfterSelect(object sender, TreeViewEventArgs e)
{
textBox1.Text = e.Node.Text;
textBox1.Focus();
}
Then subscribe the KeyDown event of the TextBox and do following in the event method:
private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.Up) || (e.KeyCode == Keys.Down))
{
treeView1.Focus();
SendKeys.Send(e.KeyCode == Keys.Up ? "{UP}" : "{DOWN}");
}
}
At last subscribe the Leave event of the TextBox and do following in the event method:
private void OnTextBoxLeave(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null)
{
treeView1.SelectedNode.Text = textBox1.Text;
}
}
And, voilá it should work like you expected it...
If you want to focus on it , you can use usercontrol. you can put your textbox on usercontrol and set focus of this textbox on usercontrol using set properties on treeview select.
No you may not, only one control may be in focus at any given time.
See Moonlight's comment for one way to achieve the behavior that you seek.

Clear MenuItem, with clear command

hi
i'm a "very" beginner in wpf
i'm trying to make a menu item "Clear", it should clear the text in the focused text box,
actually i could not find a built in command that does the job like (copy,paste,cut..etc)
is there one built in or do i have to make a custom routed command, and if so
i've tried but failed, and need ideas
i've made the ClearCommandExecuted logic, but the problem is with "CanExecute"
i tried to access the Keyboard.FocusedElement there, but failed because the focused element is the menu item it self when it's clicked !!!!
please help
thanks
You need to use one of the arguments passed into your CanExecuteQuery:
private void ClearCommandBindingCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
// e.Source is the element that is active,
if (e.Source is TextBox) // and whatever other logic you need.
{
e.CanExecute = true;
e.Handled = true;
}
}
private void ClearCommandBindingExecuted(object sender, ExecutedRoutedEventArgs e)
{
var textBox = e.Source as TextBox;
if (textBox != null)
{
textBox.Clear();
e.Handled = true;
}
}
I hope this is enough to get you headed in the right direction...
Try to use the FocusManager class. When your TextBox has lost Keyboard Focus, it still has Logical Focus, if it is inside the Focus Scope. Classes in WPF which are focus scopes by default are Window, MenuItem, ToolBar, and ContextMenu.
So using this will give you the result -
FocusManager.GetFocusedElement(winodw1); //Name of the window
For more details, read this - http://msdn.microsoft.com/en-us/library/aa969768.aspx

Categories

Resources