Ask user for element selection while a Winform is showing ?

Ask user for element selection while a Winform is showing ?

Anonymous
Not applicable
3,641 Views
6 Replies
Message 1 of 7

Ask user for element selection while a Winform is showing ?

Anonymous
Not applicable

The addin that im currenlty writing shows a simple winform when the addin is activated:

 

 

    public class MyAddin : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                if (null == commandData.Application.ActiveUIDocument.Document)
                {
                    TaskDialog.Show("Issues to Excel", "Active view is null");
                    return Result.Failed;
                }


                MyFormToShow form = new MyFormToShow(commandData);
                form.ShowDialog();
            }
            catch (Exception ex)
            {
                TaskDialog.Show("MyForm", ex.Message);
                return Result.Failed;
            }
                return Result.Succeeded;
        }
    }

So once the Winform is showing, i actually want to user to make a selecting in the active document.

 

I noticed that i can not  make a call for `Selection.PickObjects` when i am currently showing a windows form.

 

So when the winForm is showing, i want the user to make a selection (temp hide the winform) and once selection is finished i want to get the elements the user selected back to so something with in my winform.

What would be the best approach for doing so be? 

0 Likes
Accepted solutions (1)
3,642 Views
6 Replies
Replies (6)
Message 2 of 7

BardiaJahan
Advocate
Advocate
Accepted solution

You can add a button to your winform to activate Selection Mode by hiding the winform and prompting the user to select objects. (Have you tried it?)

Or you can set a timer after showing the form, then hide it and add a While loop to your execute command to run until selection is not null. (This is just an idea. wanted to know what you have already tried)

Message 3 of 7

Anonymous
Not applicable

when the button for asking a selection is called, i execute this code:

 

            UIDocument uidoc = m_commandData.Application.ActiveUIDocument;
            Document doc = uidoc.Document;
            Selection sel = uidoc.Selection;
            this.Hide();
            IList<Reference> refs = sel.PickObjects(ObjectType.Element,"Please select some elements");
            this.Show();

I can see the checkbox "multiple" and the buttons finish and  cancel in the top left, but the revit document seems to be locked (most stuff grayed out). i can not make any selection though the form is hidden.

So somehow the focus seems to be still on the Winform and blocking the revit file.

 

 

EDIT-1 :

When i change the form.ShowDialog(); to just form.Show(); it seems to be working better, though after hiding the form and finishing the selection, the form wont show again with the this.show();

 

Edit-2 :

I realized the show did work, but i just didnt set the focus back to the winform so it was right there in the background...

Seems you get codeblind after a while ^^ time for coffee

Message 4 of 7

BardiaJahan
Advocate
Advocate

Seems you get it solved.

0 Likes
Message 5 of 7

sgermanoZ2Y2F
Enthusiast
Enthusiast

Im stuck at the same spot you were where the green multiple selection bar would appear but I still had no focus on the Revit UI and its disabled. How did you solve that?

0 Likes
Message 6 of 7

B360-TylerN
Explorer
Explorer

I have a similar issue.  I have an Revit Addin that launches a WinForm.  Typically i use ".ShowDialog()" to launch the form, however when I used that to open my form it didn't allow the button my form to work properly.  The button is supposed to hide the form & let the user select an element in the Revit view, however with ".ShowDialog()" no window became active.  The form hides & I see all of my open windows (Files Explorer, Email etc.) but nothing is selectable.

 

To solve this my addin is using ".Show()" instead.  And when the button is clicked in my WinForm i use "this.Hide()" & "this.Show()".  This all works correct now where the form hides & the Revit window is my main window, where I can select an element.

 

But, now I have another big issue - performing an action/method on the elements I selected inside my transaction.  When I click another button in the form to perform this action is now says:

"starting a transaction from an external application running outside API context no allowed"

 

I have never seen that before, and I am assuming it is because my addin is using ".Show()", not ".ShowDialog()".  Not sure of a solution here, any help would be appreciated.

0 Likes
Message 7 of 7

RPTHOMAS108
Mentor
Mentor

Truth of the matter is for what you are saying you need to do you can achieve this by not exiting the Revit API context and recreating the window. You should close not hide the window and then loop back to the point of window creation in order to remain in the context. After recreating your window you can rebind it to your updated data model.

 

If you are using modeless forms with .Show then you should implement External Events to interact with Revit. In that approach you are letting the External Command that initially shows the dialogue to exit the context. You then communicate with Revit via raising external event that creates a new context when Revit is ready.

 

As noted in first paragraph however you can stay within the context via .ShowDialog for what you want to do. Code below is VB but you can achieve the same in C# with a while loop.

 

 Private Function TObj76(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result

        If commandData.Application.ActiveUIDocument Is Nothing Then Return Result.Cancelled Else
        Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
        Dim Doc As Document = UIDoc.Document
        Dim Res As List(Of String) = Nothing
Again:
        Dim SelectItemWin As New SelectElementsWindow
        SelectItemWin.ListBox_Results.ItemsSource = Nothing
        SelectItemWin.ListBox_Results.ItemsSource = Res
        SelectItemWin.ShowDialog()

        Select Case SelectItemWin.Result
            Case SelectElementsWindow.DiaResult.SelectElements
                Dim R As New List(Of Reference)
                Try
                    R = UIDoc.Selection.PickObjects(Selection.ObjectType.Element)
                Catch ex As Exception
                End Try
                If R Is Nothing = False Then
                    Res = New List(Of String)
                    For i = 0 To R.Count - 1
                        Res.Add(CStr(R(i).ElementId.IntegerValue))
                    Next
                End If

                GoTo Again
            Case Else

        End Select

        Return Result.Succeeded
    End Function

External Command

 

Public Class SelectElementsWindow
    Private IntRes As DiaResult = DiaResult.None
    Public ReadOnly Property Result As DiaResult
        Get
            Return IntRes
        End Get
    End Property
    Public Enum DiaResult
        None = 0
        SelectElements = 1
    End Enum
    Private Sub Button_Select_Click(sender As Object, e As RoutedEventArgs) Handles Button_Select.Click
        IntRes = DiaResult.SelectElements
        Me.Close()
    End Sub
End Class

Window Code Behind

<Window x:Class="SelectElementsWindow"
        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:RPT_RvtTests"
        mc:Ignorable="d"
        Title="Select Elements" Height="195.882" Width="427.647" WindowStyle="ToolWindow" ResizeMode="NoResize">
    <Grid>
        <Button Name="Button_Select" Content="Select" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75"/>
        <ListBox Name="ListBox_Results" Margin="10,35,10,10"/>
    </Grid>
</Window>

Xaml for window

 

 

0 Likes