2017-04-25 2 views
2

Je suis extrêmement nouveau à WPF et j'essaie de créer une application où je vais avoir un globe tracée dans un onglet avec une carte dans le deuxième onglet. J'ai pu obtenir le monde tracé dans une application de test, avec le code ci-dessous:ModelVisual3D ne rend pas correctement dans DockPanel

<Window x:Class="SphereTutorial.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:SphereTutorial" 
     xmlns:earth="clr-namespace:SphereTutorial.Globe" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 

     <Grid.Resources> 
      <earth:SphereMeshGenerator x:Key="SphereGeometrySource1"/> 
      <MeshGeometry3D x:Key="SphereGeometry1" 

          Positions="{Binding Source={StaticResource 
            SphereGeometrySource1}, Path=Geometry.Positions}" 

          TriangleIndices="{Binding Source={StaticResource 
            SphereGeometrySource1}, Path=Geometry.TriangleIndices}" 

          TextureCoordinates="{Binding Source={StaticResource SphereGeometrySource1}, Path=Geometry.TextureCoordinates}"/> 

     </Grid.Resources> 
     <Grid.Background> 
      Black 
     </Grid.Background> 
     <Viewport3D x:Name="mainScene3D"> 
      <Viewport3D.Camera> 
       <PerspectiveCamera x:Name="mainCam" LookDirection="-1,0,0" Position="5,0,0" UpDirection="0,1,0"/> 
      </Viewport3D.Camera> 
      <ModelVisual3D> 
       <ModelVisual3D.Content> 
        <Model3DGroup> 
         <AmbientLight Color="White"/> 
         <GeometryModel3D Geometry="{StaticResource SphereGeometry1}"> 
          <GeometryModel3D.Material> 
           <MaterialGroup> 
            <DiffuseMaterial> 
             <DiffuseMaterial.Brush> 
              <ImageBrush ImageSource="H:\C#\SphereTutorial\SphereTutorial\Images\Earth.jpg"/> 
             </DiffuseMaterial.Brush> 
            </DiffuseMaterial> 
           </MaterialGroup> 
          </GeometryModel3D.Material> 
         </GeometryModel3D> 
        </Model3DGroup> 
       </ModelVisual3D.Content> 
      </ModelVisual3D> 
     </Viewport3D> 
    </Grid> 
</Window> 

Le code de la sphère je tire de this link avec le code donné ici:

namespace VenProp.Sphere3D 
{ 
    class SphereMeshGenerator 
    { 
     private int _slices = 100; 
     private int _stacks = 50; 
     private Point3D _center = new Point3D(); 
     private double _radius = 1; 

     public int Slices 
     { 
      get { return _slices; } 
      set { _slices = value; } 
     } 

     public int Stacks 
     { 
      get { return _stacks; } 
      set { _stacks = value; } 
     } 

     public Point3D Center 
     { 
      get { return _center; } 
      set { _center = value; } 
     } 

     public double Radius 
     { 
      get { return _radius; } 
      set { _radius = value; } 
     } 

     public MeshGeometry3D Geometry 
     { 
      get 
      { 
       return CalculateMesh(); 
      } 
     } 


     private MeshGeometry3D CalculateMesh() 
     { 
      MeshGeometry3D mesh = new MeshGeometry3D(); 

      for (int stack = 0; stack <= Stacks; stack++) 
      { 
       double phi = Math.PI/2 - stack * Math.PI/Stacks; 
       double y = _radius * Math.Sin(phi); 
       double scale = -_radius * Math.Cos(phi); 

       for (int slice = 0; slice <= Slices; slice++) 
       { 
        double theta = slice * 2 * Math.PI/Slices; 
        double x = scale * Math.Sin(theta); 
        double z = scale * Math.Cos(theta); 

        Vector3D normal = new Vector3D(x, y, z); 
        mesh.Normals.Add(normal); 
        mesh.Positions.Add(normal + Center); 
        mesh.TextureCoordinates.Add(new Point((double)slice/Slices, (double)stack/Stacks)); 
       } 
      } 

      for (int stack = 0; stack <= Stacks; stack++) 
      { 
       int top = (stack + 0) * (Slices + 1); 
       int bot = (stack + 1) * (Slices + 1); 

       for (int slice = 0; slice < Slices; slice++) 
       { 
        if (stack != 0) 
        { 
         mesh.TriangleIndices.Add(top + slice); 
         mesh.TriangleIndices.Add(bot + slice); 
         mesh.TriangleIndices.Add(top + slice + 1); 
        } 

        if (stack != Stacks - 1) 
        { 
         mesh.TriangleIndices.Add(top + slice + 1); 
         mesh.TriangleIndices.Add(bot + slice); 
         mesh.TriangleIndices.Add(bot + slice + 1); 
        } 
       } 
      } 

      return mesh; 
     } 
    } 
} 

J'ai pu vérifier que cela fonctionne avec cette méthode; Cependant, quand je suis allé à mettre en œuvre la même logique dans mon application, les choses ont échoué. Pour une raison quelconque, il commence à rendre l'image sur les bords seulement. J'ai le sentiment que cela pourrait avoir à voir avec être dans un DockPanel? L'image 2D fonctionne bien dans son DockPanel. Voici le code qui ne fonctionne pas:

<Window x:Class="VenProp.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:VenProp" 
     xmlns:sphere="clr-namespace:VenProp.Sphere3D" 
     mc:Ignorable="d" 
     Title="VenProp" 
     Height="{Binding Source={x:Static SystemParameters.PrimaryScreenHeight}, Converter={local:RatioConverter}, ConverterParameter='0.9' }" 
     Width="{Binding Source={x:Static SystemParameters.PrimaryScreenWidth}, Converter={local:RatioConverter}, ConverterParameter='0.9' }" 
     WindowStartupLocation="CenterScreen" 
     Background="#FFE4E4E4"> 

    <!-- Window Resources --> 
    <Window.Resources> 
     <sphere:SphereMeshGenerator x:Key="SphereGeometrySource"/> 
     <MeshGeometry3D x:Key="SphereGeometry" 
         Positions="{Binding Source={StaticResource SphereGeometrySource}, Path=Geometry.Positions}" 
         TriangleIndices="{Binding Source={StaticResource SphereGeometrySource}, Path=Geometry.TriangleIndicies}" 
         TextureCoordinates="{Binding Source={StaticResource SphereGeometrySource}, Path=Geometry.TextureCoordinates}"/> 

    </Window.Resources> 


    <!-- Overall Container is VERTICAL--> 
    <DockPanel> 

     <!-- Top Menu --> 
     <Menu DockPanel.Dock="Top" HorizontalAlignment="Left" BorderBrush="Black"> 
      <MenuItem Header="_File"></MenuItem> 
     </Menu> 

     <!-- Main toolbar --> 
     <ToolBar DockPanel.Dock="Top"> 
      <Button> 
       <!-- Put image here--> 
      </Button> 
      <Button Content="Button2"/> 
     </ToolBar> 

     <!-- StatusBar --> 
     <StatusBar x:Name="statusBar" DockPanel.Dock="Bottom" /> 

     <!-- Inner container is horizontal --> 
     <DockPanel> 

      <Separator Width="2" Foreground="{x:Null}" Background="{x:Null}"/> 
      <!-- Throw Tree into a dock panel with its label--> 
      <StackPanel Width="310" DockPanel.Dock="Left" HorizontalAlignment="Left" Margin="0,0,0,2" Background="#FFE4E4E4"> 
       <Label Content="Object Browser" FontSize="12" Background="LightGray"/> 
       <TreeView x:Name="ObjectBrowser" BorderThickness="2" Height="620" DockPanel.Dock="Top"> 
        <TreeView.BitmapEffect> 
         <BevelBitmapEffect BevelWidth="5" Relief="0.4" LightAngle="320"/> 
        </TreeView.BitmapEffect> 
       </TreeView> 
      </StackPanel> 
     </DockPanel> 

     <Separator Width="10" Background="{x:Null}" Foreground="{x:Null}" RenderTransformOrigin="-0.45,0.541" /> 
     <!-- Tabs for graphics windows --> 
     <TabControl x:Name="tabGraphics" BorderThickness="5"> 
      <TabControl.BitmapEffect> 
       <BevelBitmapEffect BevelWidth="15" Relief="0.4"/> 
      </TabControl.BitmapEffect> 

      <!-- 3D Earth Model --> 
      <TabItem x:Name="graphics3D" Header="3D Graphics"> 
       <DockPanel Background="Black"> 
        <Viewport3D x:Name="mainScene3D"> 
         <!--Camera--> 
         <Viewport3D.Camera> 
          <PerspectiveCamera x:Name="mainCam" LookDirection="-1,0,0" Position="5,0,0" UpDirection="0,1,0"/> 
         </Viewport3D.Camera> 

         <!--Earth Model--> 
         <ModelVisual3D> 
          <ModelVisual3D.Content> 
           <Model3DGroup> 
            <AmbientLight Color="White"/> 
            <GeometryModel3D Geometry="{StaticResource SphereGeometry}"> 
             <GeometryModel3D.Material> 
              <MaterialGroup> 
               <DiffuseMaterial> 
                <DiffuseMaterial.Brush> 
                 <ImageBrush ImageSource="H:\C#\VenProp\VenProp\Images\Earth.jpg"/> 
                </DiffuseMaterial.Brush> 
               </DiffuseMaterial> 
              </MaterialGroup> 
             </GeometryModel3D.Material> 
            </GeometryModel3D> 
           </Model3DGroup> 
          </ModelVisual3D.Content> 
         </ModelVisual3D> 
        </Viewport3D> 
       </DockPanel> 
      </TabItem> 


      <TabItem x:Name="graphics2D" Header="2D Graphics"> 
       <DockPanel Background="Gray"> 
        <Image Source="H:\C#\VenProp\VenProp\Images/Earth.jpg"/> 
       </DockPanel> 
      </TabItem> 
     </TabControl> 
    </DockPanel> 
</Window> 

Pour des fins de test, si vous remplacez le ImageBrush avec, par exemple un SolidColorBrush, le même effet se produira.

Est-ce que quelqu'un a une idée de ce qui se passe? Aussi, je suis nouveau sur Stack Overflow, donc s'il y a quelque chose que je peux faire pour clarifier ma question, s'il vous plaît faites le moi savoir. Merci pour toute aide à l'avance!

Répondre

1

Vérifiez toujours votre Sortie fenêtre pour les erreurs de liaison, comme ceci:

System.Windows.Data Error: 40 : BindingExpression path error: 'TriangleIndicies' property not found on 'object' ''MeshGeometry3D' (HashCode=33785274)'. BindingExpression:Path=Geometry.TriangleIndicies; DataItem='SphereMeshGenerator' (HashCode=18281552); target element is 'MeshGeometry3D' (HashCode=34085817); target property is 'TriangleIndices' (type 'Int32Collection')

Après avoir changé de TriangleIndicies à TriangleIndices, il fonctionnait très bien:

enter image description here

+0

Merci! Je savais que c'était quelque chose de stupide. –

+0

J'ai fait Vote, cependant, puisque j'avais moins de 15 rep, il a dit que cela compterait, mais ne pas apparaître. Je viens de le faire maintenant que j'ai plus de 15. Merci encore pour votre aide! –

+0

@MikeC: Merci! – jsanalytics