Silverlight: Copy/Paste Context Menu with TextBox (Text Highlighting Issue) - wpf

I have created a TextBox control:
public class MyTextbox : TextBox
which is a just a normal TextBox, to which I have added a behavior that I have written:
public class TextBoxCutCopyPasteBehavior : Behavior<TextBox>
Everything works fine and dandy: right-clicking will display a ContextMenu with Cut, Copy, Paste options. However, the TextBox text ceases to be highlighted at that point, since the TextBox has lost focus.
What would the best way be to make the selected text remain highlighted, even after the ContextMenu appears and the TextBox loses focus?
Thank you so much for all of your help!

You should still be able to access the SelectedText property of the TextBox
private void CopyMenuItem_Click(object sender, RoutedEventArgs e)
{
string textToCopy = MyTextBox.SelectedText;
// do something
}

Related

Control does not focus

I have a WPF user control with multiple child controls and I am focusing DataGrid and TextBox programmatically with the following code:
searchTextBox.Focus();
and
productGrid.Focus();
productGrid.Focus(dataGrid); //tried this but it does not help
searchTextBox focuses normally but dataGrid does not (keyboard focus stays on some other control). Below I provided full source code that hides searchTextBox and moves focus to productGrid (searchPanel is a parent Grid of searchTextBox):
private void Execute_CancelCommand(object sender, ExecutedRoutedEventArgs e)
{
if (searchPanel.Visibility == Visibility.Visible)
{
searchPanel.Visibility = Visibility.Collapsed;
searchTextBox.Clear();
searchTextBox.Background = Brushes.White;
//the focus stays on the splitter for some reason
productGrid.Focus();
Keyboard.Focus(productGrid);
}
}
what can cause this situation?
Thnx.
It seems that productGrid.Focusable property is set to "false". You should just set it to "True" and your code should work correctly and there will be no need in calling Keyboard.Focus() method.

Setting Default Keyboard Focus On Loading A UserControl

I have an MVVM setup with a mainwindow that contains a ContentControl.
I set this to a particular viewmodel which then maps to a view.
A view is a usercontrol.
I want to be able to set the default keyboard focus to a default element in the usercontrol(View) when it loads so the application can eventually be driven just by using up, down, left, right and enter.
Some of my failed attempts are setting
FocusManager.FocusedElement="{Binding ElementName=DefaultElement}"
in my content control tag. This sets the logical focus but not the keyboard focus
I'd rather keep the solution in xaml if possable but have tried placing the following in code behind.
Keyboard.Focus(DefaultElement);
This does not work but if I popup a message box first it does. I'm a little confused as to why.
MessageBox.Show(Keyboard.FocusedElement.ToString());
Keyboard.Focus(DefaultElement);
EDIT::::
I just placed this in my onloaded event of my user control. It seems to work but can anyone see any issues that might arrise at this priority level. I.E a circumstance when the action will never run?
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
Keyboard.Focus(DefaultElement);
}));
It seems that this wpf the you have to implement a workaround on a case by case basis. The solution that seemed to work best, most of the time for me was to insert the focus code inside the dispatcher when OnVisible was changed. This sets the focus not only when the View/Usercontrol loads but also if you a changing Views by way of Visibility. If you Hide and then Show a ContentControl that is mapped to your ViewModels then the Loaded event won't fire and you'll be forced to Mouse input, or tabbing (Not so good if you want to navigate your app with a remote control).
VisibilityChanged will always fire however. This is what I ended up with for my listbox.
private void ItemsFlowListBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
ItemsFlowListBox.Focus();
ItemsFlowListBox.ScrollIntoView(ItemsFlowListBox.SelectedItem);
}));
}
}
I had the same symptom for a WPF UserControl hosted in a Winforms application. Just wanted to note I was about to try this solution when I found a normal TabIndex in the Winforms app fixed it
Per How to set which control gets the focus on application start
"The one with the minimum tab index automatically gets the focus
(assuming the TabStop property is set to true). Just set the tab
indices appropriately."
It's a tricky one with no easy answer. I'm currently doing this, although I'm not sure I like it:
public MyView()
{
InitializeComponent();
// When DataContext changes hook the txtName.TextChanged event so we can give it initial focus
DataContextChanged +=
(sender, args) =>
{
txtName.TextChanged += OnTxtNameOnTextChanged;
};
}
private void OnTxtNameOnTextChanged(object o, TextChangedEventArgs eventArgs)
{
// Setting focus will select all text in the TextBox due to the global class handler on TextBox
txtName.Focus();
// Now unhook the event handler, since it's no longer required
txtName.TextChanged -= OnTxtNameOnTextChanged;
}
And in case you're wondering what the global class handler does, it's this:
protected override void OnStartup(StartupEventArgs e)
{
...
// Register a global handler for this app-domain to select all text in a textBox when
// the textBox receives keyboard focus.
EventManager.RegisterClassHandler(
typeof (TextBox), UIElement.GotKeyboardFocusEvent,
new RoutedEventHandler((sender, args) => ((TextBox) sender).SelectAll()));
which auto selects TextBox text when receiving keyboard focus.

numericUpDown ValueChanged after MouseLeftButtonDown

I have 2 controls on a form. One numericUpDown (from the Silverlight Toolkit) and a simple Rectangle.
On the MouseLeftButtonDown of the Rectangle I popup a MessageBox with the numericUpDown value.
If I use the arrows to change the value of the numericUpDown, everyting is fine. But if I edit the value manually (with the keyboard) and immediately click on the Rectangle it shows the previous value of the numericUpDown. If I click a sencond time on the rectangle it will show the new value.
The numericUpDown.ValueChanged event is raised after the Rectangle.MouseLeftButtonDown event.
Is that a Silverlight bug? Anybody knows a workaround for that?
(btw I cannot change my Rectangle controls or events)
As workaround I propose you to create your own control like:
public class MyNumericUpDown : NumericUpDown
{
private TextBox _textBox;
public void Sync()
{
ApplyValue(_textBox.Text);
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_textBox = (TextBox)GetTemplateChild("Text");
}
}
Now you can use method Sync to syncronize display text with control Value property. You can call method from XAML declaratively or in code behind. In your case:
private void Rectangle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
myNumericUpDown.Sync();
MessageBox.Show(myNumericUpDown.Value.ToString());
}

How to get access to generated text box inside Silverlight DataForm?

I have a DataForm bound to a simple object that has some text fields. The DataForm correctly auto generates a TextBox for each of the string fields. From code I now need to set the focus to one of those generated TextBox elemetns. How do you get the generated element from the DataForm so I can set focus to it?
Use AutoGeneratingField event of DataForm.
Here is example how to get property with name ID
void dataForm1_AutoGeneratingField(object sender, DataFormAutoGeneratingFieldEventArgs e)
{
if (e.PropertyName == "ID")
{
// set focus
}
}

focus does not enter targeted user control properly

I've got a user control, consisting of a text box and two buttons.
the control is placed on a dialog box and when i tab over the dialog
controls, I experience proper behavior - first the text box is focused,
then one button, then the other.
However, when I set the user control as a target of a keyboard shortcut
set with "_" for a label (say press alt+r for "_Row count") the user control
does not receive any focus. Tried implementing "gotkeyboardfocus" and setting
the focus to the textbox control there but it doesn't work.
A UserControl isn't focusable by default so you have to turn it on in order to get this to work.
<my:UserControl1 x:Name="userControl11" Focusable="True" .../>
<Label Target="userControl11">_Row count</Label>
And then you can focus the desired TextBox inside of the UserControl when it recieves Focus
private void UserControl_GotFocus(object sender, RoutedEventArgs e)
{
textBox.Focus();
}
Hi I recently encountered focus problem. What I did is create a method called SetFocus() from inside my user control. Then inside that usercontrol I set the focus directly to my textbox control after calling .SetFocus() from consumer.
public void SetFocus()
{
this.txtCommand.Focus();
}

Resources