0

question edited to provide a better explanation

I am using a treeview consisting of a stackpanel with a textblock and a textbox inside. What I would like to achieve is the total selection of the text when the textbox appears. The textblock disappears by double-clicking or selecting an option from a context menu, giving visibility to the textbox to rename the item. I'd like to have the selectall on the MouseLeftButtonDown on the textblock and also on click on a context menu option.

My treeview is contained in the MainWindow and, the stackpanel (with the text block and the textbox) is in a different file and I dynamically add it to the tree view depending on the user's action. When I click on the StackPanel the first click highlights it, on double-click it opens a page and, on the MouseLeftButtonDown (and on click in a contextmenu option) I change the visibility of the textblock with the textbox and here I want the selectall() event to get fired.

I tried the following code and it only works halfway:

private void mniRename_Click(object sender, RoutedEventArgs e)
{
     prevSelected.MyTextBlock.Visibility = Visibility.Collapsed;
     prevSelected.MyTextBox.Visibility = Visibility.Visible;
     prevSelected.MyTextBox.Focus();

     if (prevSelected.MyTextBox.IsFocused)
     {
         prevSelected.MyTextBox.SelectAll();
     }

     prevSelected.MyTextBox.Text = prevSelected.MyTextBlock.Text;
}

The issue is that the SelectAll() event doesn't work on the first click while the Focus() works, then on the following clicks everything works fine. The code is always executed in the same way.

Does anyone have any idea why this happens?

bidibi
  • 13
  • 6
  • WPF can be odd sometimes about actual instantiation. I'll leave someone who knows better to actually answer this, but my guess is that the first time, the control is trying to finish an actual initial render and cannot yet be focused. Timing, really. The 2nd time, it's fully fleshed out and the focus works. That happens sometimes when a control is not shown initially, but becomes visible later, as you are doing. – DonBoitnott Sep 13 '21 at 17:06
  • Hello, what will happen if you remove the if statement, I mean if you just write prev.Selected.MyTextBox.SelectAll(); with no if? – Dark Templar Sep 13 '21 at 17:07
  • I think you may use Inputbinding, something like described [here](https://stackoverflow.com/a/6882619/2408978). If you are not familiar with Commands, I could write some sample code as an answer. :-) – dba Sep 13 '21 at 17:27
  • @DonBoitnott Hello, I'm sorry but I didn't mention that the first time the focus event is rendered but not the selectall! – bidibi Sep 14 '21 at 06:34
  • @DarkTemplar Hello! Actually, the if statement is quite useless. Its behavior is the same: on the first click, it triggers both events but renders only the focus event. The following times it renders the focus and the selectall too. – bidibi Sep 14 '21 at 06:43
  • @dba Hey! I'm not sure that I'm doing the binding in the right way. It would be great if you could show me a sample, thanks in advance :) – bidibi Sep 14 '21 at 06:45
  • Showing the concept in an Answer would be long and maybe confusing because of the several classes and so on. I uploaded a [sample solution](https://github.com/dbalogh78/WPF.InputBinging.Sample.git) to GitHub. You may take a look (Bear in mind, this is one possible approach, there are plenty ways to achieve this :-) ) – dba Sep 27 '21 at 15:19

1 Answers1

0

No really sure what you want to achieve. but what you describe can be achieved by the following code:

XAML

<StackPanel Orientation="Horizontal">
    <TextBox x:Name="MyTextBox" LostFocus="MyTextBox_OnLostFocus" Width="100"/>
    <TextBlock x:Name="MyTextBlock" Text="{Binding ElementName=MyTextBox, Path=Text}" MouseLeftButtonDown="MyTextBlock_OnMouseLeftButtonDown"/>
</StackPanel>

C#

private void MyTextBox_OnLostFocus(object sender, RoutedEventArgs e)
{
    MyTextBox.Visibility = Visibility.Hidden;
    MyTextBlock.Visibility = Visibility.Visible;
}

private void MyTextBlock_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    MyTextBlock.Visibility = Visibility.Collapsed;
    MyTextBox.Visibility = Visibility.Visible;
    MyTextBox.Focus();
    MyTextBox.SelectAll();
}
Nawed Nabi Zada
  • 2,819
  • 5
  • 29
  • 40
  • I tried but selectall never works. I can provide a better explanation: I'd like to have the selectall on the MouseLeftButtonDown on the text block and also on click on a context menu option. I've a treeview in the MainWindow and, I've the stackpanel with the text block and the textbox in a different file and I dynamically add it to the tree view depending on the user's action. When I click on the StackPanel the first click highlights it, on double-click, it opens a page and on the MouseLeftButtonDown, I change the visibility of the text block with the text box and here I want the selectall. – bidibi Sep 14 '21 at 09:02
  • Well... instead of the explanation, please edit your question and add a full reproducible code. That way people quickly can see the issue. now we have to guess. – Nawed Nabi Zada Sep 14 '21 at 09:11