TBC Macros and Extensions

 View Only
Expand all | Collapse all

modeless/non-modal window with textbox/datagrid entry

  • 1.  modeless/non-modal window with textbox/datagrid entry

    Posted 05-29-2024 04:24

    Hi,

    I'm working on a new macro where I want the window to be separate from the TBC window but the viewport still accessible. It'll contain a rather large table, hence I don't want it squeezed into the usual place and also still easy access to a second macro window. I know that I can float that dock. But I'd prefer to have my window completely separate. Until I find a solution to the conundrum that I maneuvered myself into, I'll have to use the normal float solution.

    The sample macros "ListProjectObjects" and "ViewProjectData" show how to create a modal window where you can't interact with TBC anymore

    def Setup(cmdData, macroFileFolder):
        #cmdData.UIForm = "SCR_Inspect12dAttributes"  # must be disabled
    
    def Execute(cmd, currentProject, macroFileFolder, parameters): 
            form = ListProjectObjectsDialog(currentProject, macroFileFolder).ShowDialog()
            return
    
    class ListProjectObjectsDialog(Window): # this inherits from the WPF window control
        def __init__(self, currentProject, macroFileFolder):
            with StreamReader(macroFileFolder + r"\ListProjectObjects.xaml") as s:
                wpf.LoadComponent(self, s) 
    <Window
            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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1"
            mc:Ignorable="d"
            Title="Objects in Project" Height="400" Width="400" MinHeight="100" MinWidth="200">
        <Grid Margin="0,0,0.2,-0.2" >
      

    If you change

    def Execute(cmd, currentProject, macroFileFolder, parameters): 
            form = ListProjectObjectsDialog(currentProject, macroFileFolder).ShowDialog()

    to

    def Execute(cmd, currentProject, macroFileFolder, parameters):
        form = SCR_Inspect12dAttributesDialog(currentProject, macroFileFolder).Show()
        return
        # .Show() - is non modal - you can interact with the drawing window
        # .ShowDialog() - is modal - you CAN NOT interact with the drawing window

    the window will be floating and the user can still select objects on the screen.

    BUT, here comes the catch, textboxes or datagrids won't get keyboard entries anymore. They go into edit mode, and you can drag characters around with the mouse, but it completely ignores the keyboard.

    First I thought my DataGrid implementation is wrong and it drove me nuts for hours. (({..})) Until I had the epiphany to switch the window back to modal, and it suddenly worked. (headbang)

    This is not a TBC bug. Once I found the actual reason I did find forum entries that suggest that this is a WPF bug, or at least shortcoming.

    They suggest to call "EnableModelessKeyboardInterop" from the application that is creating the window, which would be TBC itself.

    Has anybody tried that kind of modeless window before and found a workaround for the ignored keyboard?

    I did find the entry "UIViewForm" while inspecting the variable cmdData during startup.

    If I set

    def Setup(cmdData, macroFileFolder):
        cmdData.UIViewForm = "SCR_Inspect12dAttributes"
    
    class SCR_Inspect12dAttributes(Grid):
    

    I end up with an extra tab besides the plan view. Not too bad, but I need to find out how to float that one. Right click in that view doesn't show "Float".

     



    ------------------------------
    Ronny Schneider
    ------------------------------


  • 2.  RE: modeless/non-modal window with textbox/datagrid entry
    Best Answer

    Posted 09-23-2024 01:29

    Hi Ronny,

    Perhaps you already have solved this..

    I was trying to do something similar. I am not sure what you are trying to achieve but I was able to manage a floating window and textboxes keyboard entries in this way:



    ------------------------------
    Andrea Zanetti
    ------------------------------



  • 3.  RE: modeless/non-modal window with textbox/datagrid entry

    Posted 09-23-2024 23:30

    Hi Andrea,

    no I haven't looked into it anymore, but your message sounds promising. I'll give it a try as soon as I can.



    ------------------------------
    Ronny Schneider
    ------------------------------



  • 4.  RE: modeless/non-modal window with textbox/datagrid entry

    Posted 09-24-2024 00:20

    Haven't looked in depth yet, just came across the first issue.

    How did you reference the System.Windows.Forms.Integration, it complains that it can't find "Integration".



    ------------------------------
    Ronny Schneider
    ------------------------------



  • 5.  RE: modeless/non-modal window with textbox/datagrid entry

    Posted 09-24-2024 12:05
    clr.AddReference('WindowsFormsIntegration')


    ------------------------------
    Andrea Zanetti
    ------------------------------



  • 6.  RE: modeless/non-modal window with textbox/datagrid entry

    Posted 09-24-2024 22:08

    Thanks, very unusual reference for this one.

    But it all works, awesome, thanks for that.

    Still have some work to do now. I want to save the window size and location and restore it during the next start. Saving and restoring is no issue, but I need to make sure that the window is visible on any of the screens. If the screen constellation/arrangement did change since the last use, it could be possible that the window is placed outside the current desktop area. I think it should be possible to check it against "System.Windows.Forms.Screen.AllScreens" and if it's outside to use some fallback values.



    ------------------------------
    Ronny Schneider
    ------------------------------