Popup -> Insert snippet -> Editor loses focus

SyntaxEditor for WPF Forum

Posted 4 years ago by Dirk Zellerfeld
Version: 19.1.0685
Platform: .NET 3.0 (Core)
Environment: Windows 10 (64-bit)
Avatar

I've added a keyboard shortcut to insert snippet which works fine. However unlike in non-popup context the SyntaxEditor loses its focus, focus gets set back to the main window as soon as I've chosen the snippet to insert. How can I ensure the focus gets set to the editor instead? Or is this something you can fix?

The following XAML has been simplified for reading purpose:

<Window>
	<Popup
	Placement="Bottom"
	PlacementTarget="{Binding ElementName=BtnTest}"
	StaysOpen="False">
	<Border>
		<syntaxeditor:SyntaxEditor>
			<syntaxeditor:EditorDocument />
			<syntaxeditor:SyntaxEditor.InputBindings>
				<KeyBinding Key="S" Modifiers="Alt" Command="syntaxeditor:EditorCommands.RequestIntelliPromptInsertSnippetSession"/>
			</syntaxeditor:SyntaxEditor.InputBindings>
		</syntaxeditor:SyntaxEditor>
	</Border>
	</Popup>
</Window>

Comments (5)

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

Thanks for letting us know.  We've fixed this for the next maintenance release.


Actipro Software Support

Posted 4 years ago by Dirk Zellerfeld
Avatar

I can confirm its fixed in last version. However there is a new bug: the popup no longer closes when clicked outside (StaysOpen=false). Instead I have to manually click inside the popup and then click outside the popup.

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Dirk,

Hmm, I'm not seeing this when I paste this code into our main SyntaxEditor SDI Editor demo and try to reproduce it:

<Button x:Name="BtnTest" Click="BtnTest_Click" Content="Test" DockPanel.Dock="Top" />
<Popup x:Name="popup" Placement="Bottom" PlacementTarget="{Binding ElementName=BtnTest}" StaysOpen="False">
	<Border Width="500" Height="300">
		<editor:SyntaxEditor x:Name="editor2">
			<editor:EditorDocument />
			<editor:SyntaxEditor.InputBindings>
				<KeyBinding Key="S" Modifiers="Alt" Command="editor:EditorCommands.RequestIntelliPromptInsertSnippetSession"/>
			</editor:SyntaxEditor.InputBindings>
		</editor:SyntaxEditor>
	</Border>
</Popup>
		private void BtnTest_Click(object sender, RoutedEventArgs e) {
			editor2.Document.Language = editor.Document.Language;
			popup.IsOpen = true;
		}

Can you try the same code and let us know the exact steps to reproduce?


Actipro Software Support

Posted 4 years ago by Dirk Zellerfeld
Avatar

This is my code I copied into a new WPF .NET Core 3.1 application

<Window
    x:Class="ActiProTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:ActiProTest"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:shared="http://schemas.actiprosoftware.com/winfx/xaml/shared"
    xmlns:syntaxeditor="http://schemas.actiprosoftware.com/winfx/xaml/syntaxeditor"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <Button Name="BtnAbc" Margin="279,149,412,217">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <EventTrigger.Actions>
                        <BeginStoryboard>
                            <Storyboard>
                                <BooleanAnimationUsingKeyFrames Storyboard.TargetName="Popup1" Storyboard.TargetProperty="IsOpen">
                                    <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True" />
                                </BooleanAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger.Actions>
                </EventTrigger>
            </Button.Triggers>
            Test
        </Button>
        <Popup
            Name="Popup1"
            Placement="Bottom"
            PlacementTarget="{Binding ElementName=BtnAbc}"
            StaysOpen="False">
            <Border
                Background="White"
                BorderBrush="Black"
                BorderThickness="1">
                <shared:ResizableContentControl
                    x:Name="resizablePopup"
                    Width="400"
                    Height="200">
                    <syntaxeditor:SyntaxEditor
                        x:Name="Editor123"
                        VerticalContentAlignment="Top"
                        AcceptsTab="True"
                        AreWordWrapGlyphsVisible="True"
                        HasHorizontalSplit="False"
                        HorizontalScrollBarVisibility="Visible"
                        IsTextDataBindingEnabled="True"
                        IsWordWrapEnabled="True"
                        Loaded="custom_Loaded"
                        Text="{Binding Instruction, UpdateSourceTrigger=PropertyChanged}"
                        VerticalScrollBarVisibility="Visible">
                        <syntaxeditor:EditorDocument />
                        <syntaxeditor:SyntaxEditor.InputBindings>
                            <KeyBinding
                                Key="S"
                                Command="syntaxeditor:EditorCommands.RequestIntelliPromptInsertSnippetSession"
                                Modifiers="Alt" />
                        </syntaxeditor:SyntaxEditor.InputBindings>
                    </syntaxeditor:SyntaxEditor>
                </shared:ResizableContentControl>
            </Border>
        </Popup>
    </Grid>
</Window>
using ActiproSoftware.Windows.Controls.SyntaxEditor;
using ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt;
using ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation;
using System.IO;
using System.Windows;

namespace ActiProTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void custom_Loaded(object sender, RoutedEventArgs e)
        {
            ((SyntaxEditor)sender).Document.Language.RegisterService(new CodeSnippetProvider
            {
                RootFolder = LoadCodeSnippetFolderFromResources()
            });
            new DisplayItemClassificationTypeProvider().RegisterAll();
        }

        static ICodeSnippetFolder LoadCodeSnippetFolderFromResources()
        {
            var snippetsFolder = new CodeSnippetFolder("snippets");
            CodeSnippetSerializer serializer = new CodeSnippetSerializer();
            foreach (string path in Directory.GetFiles(Path.Combine(@"C:\Users\Dirk\Documents\Actipro Software\WPF-Controls\v19.1.0686\SampleBrowser\ProductSamples\SyntaxEditorSamples\Languages\Snippets\CSharp"), "*.snippet"))
            {
                foreach (var snippet in serializer.LoadFromFile(path))
                    snippetsFolder.Items.Add(snippet);
            }

            return snippetsFolder;
        }
    }
}

and this is a GIF demonstrating the issue: https://imgur.com/a/SZZRzbH

1. I click on the button

2. I click inside the popup

3. I press ALT+S

4. I click on for snippet

5. I click outside of the popup, popup stays opened

6. I click inside popup and then outside popup and popup closes as expected.

Posted 4 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Thanks for the updated code and video.  I can see it happening now, even with a normal Ctrl+Space completion session in a modified version of your scenario.  From what I can tell, it only happens if you double-click the completion listbox, which selects/commits an item.  The completion mechanism is also used by the code snippet selection session (your scenario).  Single-clicking on the list and pressing Enter doesn't seem to cause it.

I noticed that in your popup scenario, keyboard focus seemed to be getting put back to the root Window and it's not clear why.  If we manually tell the view to Focus() before executing a double-click-based Commit(), we see the keyboard focus in the view after the commit completes.  But the problem you have with the popup mouse capture being broken still exists.

Digging in for a while more, we found that it seems like it's the WPF ListBox's handling of mouse capture that triggers the problem.  We found that before we call Commit(), we can tell the ListBox to ReleaseMouseCapture(), and that resolves the issue.  This change will go into the 2020.1 version.


Actipro Software Support

The latest build of this product (v24.1.1) was released 2 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.