A requirement for a recent project is to click a part of the WPF 3D model and perform subsequent operations on it. For example, you can obtain the data of this Part and display the graph)
First.
I selected a square to show the square in blue, and sat on the screen to show the operation after clicking the square.
I handled two problems throughout the process:
1. How to Select this part of the model
2. How to maintain this part of your choice
Question 1: How to Select this part of the model
In the WPF 3D model, only the Viewport3D object has the MouseButtonLeftDown event, but a part of the model does not. Therefore, we need to use VisualTreeHelper. HitTest to determine which model is clicked, and this model must be used externally. Therefore, we have customized a ModelVisual3DSelectedEventHandler event for external calls.
1 // customize the EventHandler selected by a model
2 public class Visual3DEventArgs: EventArgs
3 {
4 public ModelVisual3D Visual3D {get; set ;}
5
6 public Visual3DEventArgs (ModelVisual3D modelVisual3D)
7 {
8 this. Visual3D = modelVisual3D;
9}
10}
11
12 public delegate void ModelVisual3DSelectedEventHandler (object sender, Visual3DEventArgs args );
13 //....
14
15 // declare the LeftButton event of Viewport3D
16 ViewPort. MouseLeftButtonDown + = ViewPort_MouseLeftButtonDown;
17
18 // Viewport LeftButton Function
19 void ViewPort_MouseLeftButtonDown (object sender, System. Windows. Input. MouseButtonEventArgs args)
20 {
21 Point mousePos = args. GetPosition (ViewPort );
22 var hitParams = new PointHitTestParameters (mousePos );
23 VisualTreeHelper. HitTest (ViewPort, null, ResultCallback, hitParams );
24}
25
26 // processing after HitTest is selected
27 private HitTestResultBehavior ResultCallback (HitTestResult result)
28 {
29 RayHitTestResult rayResult = result as RayHitTestResult;
30
31 if (rayResult! = Null)
32 {
33 var visual3D = result. VisualHit as ModelVisual3D;
34 if (visual3D! = Null)
35 {
36 if (OnModelSelected! = Null)
37 {
38 OnModelSelected (this, new Visual3DEventArgs (visual3D ));
39}
40
41 return HitTestResultBehavior. Stop;
42}
43
44}
45 return HitTestResultBehavior. Continue;
46}
2. Question 2: How to maintain the part you select
I have just obtained the selected model in Visual3DEventArgs, and now I can operate on it. Maybe there is a model in the database called "block1", searching for data and so on .... however, although ModelVisual3D has x: name in The xaml file, ModelVisual3D does not have ModelVisual3D. even if you obtain this model, you can only perform basic rendering on it, and there is no way to perform logical operations (such as database communication ).
The object can be obtained only through viewport3D. FindName (string name!
Solution: we can maintain a model name table (which is actually an xml file) by ourselves ):
<Sections>
<Section>
<Name> dg01 </Name>
</Section>
<Section>
<Name> dg02 </Name>
</Section>
<Section>
<Name> dg04 </Name>
</Section>
</Sections>
Then define a function with the returned Name:
1 public Section GetSelSection (ModelVisual3D visual3D)
2 {
3 if (_ context! = Null & _ context. Sections! = Null & visual3D! = Null)
4 {
5 var viewPort = _ context. Model. ViewPort;
6
7 foreach (var section in _ context. Sections)
8 {
9 if (viewPort. FindName (section. Name) = visual3D)
10 {
11 return section;
12}
13}
14}
15
17 return null;
18}
I can get this section object through GetSelSection (args. Visual3D. By the way, this Section is the ing Class of the XML file just now. And database operations to use this Section.