Used PreviewControl(ElementHost & PickPoint

Used PreviewControl(ElementHost & PickPoint

Ysuuny
Contributor Contributor
1,753 Views
13 Replies
Message 1 of 14

Used PreviewControl(ElementHost & PickPoint

Ysuuny
Contributor
Contributor

Hi,

I'm try to used PickPoint method in winform.

When the PreviewControl is not in the winform, it's run well!

But, the PreviewControl is in the winform... It's not working...

 

class TestEventHandler(IExternalEventHandler):
    def Execute(self, aa):
        try:
            # All the SnapTypes
            snapTypes = ObjectSnapTypes.Endpoints | ObjectSnapTypes.Midpoints | ObjectSnapTypes.WorkPlaneGrid | ObjectSnapTypes.Intersections | ObjectSnapTypes.Centers | ObjectSnapTypes.Perpendicular | ObjectSnapTypes.Points       
            PickPoint(snapTypes, "Pick Point")
  
        except Exception as e:
            print(e) 
            
    def GetName(self):
        return "TestEventHandler"

test_event_handler = TestEventHandler()           
ext_event = ExternalEvent.Create(test_event_handler)

class Test_Gui(Form):
    def __init__(self):
        self.btn_pickPoint = Button(Text = "Pick Point")
        self.btn_pickPoint.Location = Point(25, 5 +obj_hight)
        self.btn_pickPoint.Width = 100
        self.btn_pickPoint.Height = 50
        self.btn_pickPoint.Click += self.pick_pt
        
        currentViewId = uidoc_view.Id

        preview = PreviewControl(doc, currentViewId)
        elementHost = Integration.ElementHost()
        elementHost.Location = Point(0,0)
        elementHost.Dock = DockStyle.None
        elementHost.Size = Size(1100, 510)
        elementHost.TabIndex = 0
        elementHost.Parent = self
        elementHost.Child = preview
        elementHost.Location = Point(25, 5.4)
        
        self.Controls.Add(self.btn_pickPoint)
        self.Controls.Add(elementHost)
        
        self.Width = 1200
        self.Height = 980
    
    def pick_pt(self, sender, e):  
        test = ext_event.Raise()

def main():
    try:
        #Test_Gui().Show()
        Application.Run(Test_Gui())    

    except Exception as ex:
        print(ex)

▲The above code is part of the code. 

Please help me...

0 Likes
Accepted solutions (1)
1,754 Views
13 Replies
Replies (13)
Message 2 of 14

sonicer
Collaborator
Collaborator

The dialog or form or window host this preview control must be modal.

 

0 Likes
Message 3 of 14

Ysuuny
Contributor
Contributor

I'm already used model form...  (Application.Run())

Ummm..... This isn't it?

0 Likes
Message 4 of 14

jeremytammik
Autodesk
Autodesk
Accepted solution

If you display a modal form in your Revit external command, it will block all other interaction with Revit, so you will not be able to use the PickPoint method while the form is open. I do not understand why you say that you can.

 

If you display a PreviewControl within your modal form, or anywhere else, for that matter, it does not provide any support for the PickPoint method. 

 

The PickPoint method only supports user selection in the Revit graphics screen, interacting directly with the Revit BIM model in the current active document.

 

The PreviewControl does not support any picking, or any other interaction either, for that matter, except pan and zoom.

 

The PreviewControl is a pure preview control, providing read-only access and no user interaction with the model.

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 5 of 14

Anonymous
Not applicable

Jeremy,

 

This isn't entirely true.  When changing the orientation/rotation of a 3D view inside of a PreviewControl window, the model's 3D view will rotate as well.  Zoom/Pan do not have this effect.

 

-Scott

0 Likes
Message 6 of 14

jeremytammik
Autodesk
Autodesk

Wow! Brilliant. Thank you very much for pointing that out!

 

I guess that is why it requires a transaction, then... I seem to remember something like that. It does, doesn't it?

  



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 7 of 14

Anonymous
Not applicable

Oddly enough -- no, it doesn't require it!  This could be like the PromptForFamilyInstancePlacement method which has a transaction control built in. The PreviewControl class is full of Event Handlers so maybe this is the case?

 

Here's the very basic sample of the external command I used to test this for 3D views.

 

[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)]
    class PreviewControlTest : IExternalCommand
    {
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            UIApplication uiapp = commandData.Application;
            UIDocument uidoc = uiapp.ActiveUIDocument;
            Document doc = uidoc.Document;

            WPF_GridContainer newGrid = new WPF_GridContainer();
            newGrid.theGrid.Children.Add(new PreviewControl(doc, new FilteredElementCollector(doc).OfClass(typeof(View3D)).FirstElementId()));
            newGrid.ShowDialog();

            return Result.Succeeded;
        }
    }

  

0 Likes
Message 8 of 14

jeremytammik
Autodesk
Autodesk

Well, I remember some issue with transactions ... I assume it will refuse to run in read-only transaction mode, then...

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 9 of 14

Anonymous
Not applicable

Jeremy,

 

I can confirm. Switching the TransactionMode to ReadOnly is now just hanging the command (never opens the window for the PreviewControl).

 

Funky stuff, but good to know!

0 Likes
Message 10 of 14

jeremytammik
Autodesk
Autodesk

Dear Scott,

 

Thank you for your research and confirmation. I shared them for posterity on the blog:

 

https://thebuildingcoder.typepad.com/blog/2020/09/code-signing-preview-and-element-type-predicates.h...

 

Cheers,

 

Jeremy

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

0 Likes
Message 11 of 14

Anonymous
Not applicable

Question 1: About PickPoint

Using WPF form CAN call 'PickPoint' on modal, but Windows Forms CANNOT do it. You can try it. I think that .NET has some inner problems.

My Solution: To solve it, I will call 'PickPoint' on IExterlCommand method.

 

Question 2: About PreviewControl

I don't sure the control can working on model or modaless. I think it work on modal. Bucause, if using EXTERNAL EVENT to do, UI refreshing is very difficult to me when working on window form.

 

NOTE: I don't know about the result of wpf test. You can tell me! 🙂

 

Summary:

1. Using modal to show form/window.

2. If you use win form, calling 'PickPoint' method on  your 'IExternalCommand'.

0 Likes
Message 12 of 14

Anonymous
Not applicable

kelicto,

 

I don't think the PickPoint in Win Forms is the same as the PickPoint you need for your Revit context.  As Jeremy says earlier:

 

If you display a modal form in your Revit external command, it will block all other interaction with Revit, so you will not be able to use the PickPoint method while the form is open. I do not understand why you say that you can.

PickPoint here is the UIDocument.Selection PickPoint which is from within the Revit Context and refers to a point in the coordinate space inside the model.  The PickPoint method on your form will tell you about points on your screen perhaps, but nothing relating to a point in a Revit model.

 

If you know of a way to transform a point from a canvas... maybe with the PreviewControl on the canvas... then maybe you can use some sort of extension method to approximate the point you need in the Revit model.

 

Cheers,

Scott

0 Likes
Message 13 of 14

Anonymous
Not applicable

About PickPoint:

[Transaction(TransactionMode.Manual)]
[Regeneration(RegenerationOption.Manual)]
internal class GridSettingCmd : BaseCommand
{
    public override void Run(ref string message, ElementSet elements)
    {
      var location = _uiDoc.Selection.PickPoint(Resources.Msg_GridInsertionPoint);

      new GridMainForm(_doc, location).ShowDialogPlus();
    }
}

The best way that click 'ok' button to call 'PickPoint', but can't achieve this function on winform. So,  I think using WPF to do.

 

Point Transform: 

I think 'The way to transform a point from a canvas' is very difficult. Bucause we don't have a suitable reference, best way is using WPF to do!

0 Likes
Message 14 of 14

Anonymous
Not applicable

Window Form can complete all tasks. Click 'Ok' button don't call 'PickPoint', you should call it on your command.

It's a very easy way, but I try to use 'Iding' event to do... I think 'Iding' cannot be achieved. 😂

    [Transaction(TransactionMode.Manual)]
    [Regeneration(RegenerationOption.Manual)]
    public class ButtonAutoClickingCmd : BaseCommand
    {
        public override void Run(ref string message, ElementSet elements)
        {
            var frm = new TestForm(_uiApp);

            frm.ShowDialog();

            _uiApp.ActiveUIDocument.Selection.PickPoint("xxx");

            using (var trans = new TransactionWrapper(_doc, "xxx"))
            {
                var lvl = _doc.First<Level>();

                Wall.Create(_doc, Line.CreateBound(XYZ.Zero, new XYZ(10, 0, 0)), lvl.Id, false);

                trans.Commit();
            }
        }
    }

 

0 Likes