title: Why is the Binding of the Point3DCollection not working?
body: <p><strong>Hey there,</strong></p>
  
  <p>the generation of my Point3DCollection works fine and i get the Mesh in the Viewport3D (<a href="https://imgur.com/5Hzitw2" rel="nofollow noreferrer">https://imgur.com/5Hzitw2</a>), but the calculateNoise() doesnt update my bound Positions in the Viewport3D even though the OnPropertyChanged Method in my ViewModel get's called. What am I doing wrong here? </p>
  
  <p>Thanks in advance, 
  KonstIT</p>
  
  <p>XAML:</p>
  
  <pre><code>&lt;Viewport3D&gt;
      &lt;Viewport3D.Camera&gt;
          &lt;PerspectiveCamera x:Name="camera"/&gt;
      &lt;/Viewport3D.Camera&gt;
      &lt;ModelVisual3D&gt;
          &lt;ModelVisual3D.Content&gt;
              &lt;Model3DGroup&gt;
                  &lt;DirectionalLight Color="White" Direction="-1, -1, -3" /&gt;
                  &lt;GeometryModel3D&gt;
                      &lt;GeometryModel3D.Geometry&gt;
                          &lt;MeshGeometry3D Positions="{Binding Positions}" TriangleIndices="{Binding TriangleIndices}"/&gt;
                      &lt;/GeometryModel3D.Geometry&gt;
                      &lt;GeometryModel3D.Material&gt;
                          &lt;DiffuseMaterial Brush="White"/&gt;
                      &lt;/GeometryModel3D.Material&gt;
                  &lt;/GeometryModel3D&gt;
              &lt;/Model3DGroup&gt;
          &lt;/ModelVisual3D.Content&gt;
      &lt;/ModelVisual3D&gt;
  &lt;/Viewport3D&gt;
  </code></pre>
  
  <p>ViewportViewModel:</p>
  
  <pre><code> internal class ViewportViewModel : INotifyPropertyChanged
   {
       private int _terrainSize;
       private Point3DCollection _positions;
       private Int32Collection _triangleIndices;
       private Random random = new Random();
  
       public Point3DCollection Positions
          {
              get
              {
                  return _positions;
              }
              set
              {
                  _positions = value;
                  OnPropertyChanged("Positions");
              }
          }
       public Int32Collection TriangleIndices
          {
              get
              {
                  return _triangleIndices;
              }
              set
              {
                  _triangleIndices = value;
                  OnPropertyChanged("TriangleIndices");
              }
          }
  
       public ViewportViewModel()
       {
           _terrainSize = 56;
           _positions = new Point3DCollection();
           _triangleIndices = new Int32Collection();
           GeneratePositions();
           GenerateTriangleIndices();
           CalculateNoiseCommand = new CalculateNoiseCommand(this);
       }
  
       private void GeneratePositions()
          { //Works }
  
       private void GenerateTriangleIndices()
          { //Works }
  
       //Handling
       ...
  
       internal void CalculateNoise()
       {
           for (int i = 0; i &lt; _terrainSize * _terrainSize; i++)
           {
               Point3D point = new Point3D();
               point = Positions[i];
               point.Y = random.Next(10) / 10.0;
               Positions[i] = point;
           }
           OnPropertyChanged("Positions");
       }
  
       #region INotifyPropertyChanged Members
  
          public event PropertyChangedEventHandler PropertyChanged;
          private void OnPropertyChanged(string propertyName)
          {
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                  Console.WriteLine("ViewportViewModel: " + propertyName);
              }
          }
  
          #endregion
  
   }
  
  </code></pre>
  
  <p>The Code to replace the current Point3DCollection. It's the same as the GeneratePositions() which is called at the constructor, just with the Positions.Clear() method at the beginning. It's called via the CalculateNoise().</p>
  
  <pre><code>        private void ReplacePositions()
          {
              if(Positions.Count &gt; 0)
              {
                  Positions.Clear();
              }
  
              var column = 0;
              var row = 0;
              Point3D point = new Point3D();
  
              for (int i = 0; i &lt; _terrainSize * _terrainSize; i++)
              {
                  for (int j = 0; j &lt; 3; j++)
                  {
                      if (j == 0)
                          point.X = ((float)column / ((float)_terrainSize - 1) - 0.5) * 2;
                      if (j == 1)
                          point.Y = 0;
                      if (j == 2)
                          point.Z = ((float)row / ((float)_terrainSize - 1) - 0.5) * 2;
                  }
  
                  Positions.Add(point);
  
                  // Calculate next row &amp; column
                  column++;
                  if (column % _terrainSize == 0)
                  {
                      row++;
                  }
                  column %= _terrainSize;
              }
          }
  
          internal void CalculateNoise()
          {
              ReplacePositions();
              OnPropertyChanged("Positions");
          }
  </code></pre>