Почему Привязка Point3DCollection не работает? - PullRequest
0 голосов
/ 23 апреля 2019

Привет,

генерация моей коллекции Point3DCollection работает нормально, и я получаю сетку в Viewport3D (https://imgur.com/5Hzitw2),, но CalculateNoise () не обновляет мои связанные позициив Viewport3D, хотя метод OnPropertyChanged в моем ViewModel get вызывается. Что я здесь не так делаю?

Заранее спасибо, KonstIT

XAML:

<Viewport3D>
    <Viewport3D.Camera>
        <PerspectiveCamera x:Name="camera"/>
    </Viewport3D.Camera>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <Model3DGroup>
                <DirectionalLight Color="White" Direction="-1, -1, -3" />
                <GeometryModel3D>
                    <GeometryModel3D.Geometry>
                        <MeshGeometry3D Positions="{Binding Positions}" TriangleIndices="{Binding TriangleIndices}"/>
                    </GeometryModel3D.Geometry>
                    <GeometryModel3D.Material>
                        <DiffuseMaterial Brush="White"/>
                    </GeometryModel3D.Material>
                </GeometryModel3D>
            </Model3DGroup>
        </ModelVisual3D.Content>
    </ModelVisual3D>
</Viewport3D>

ViewportViewModel:

 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 < _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

 }

Код для замены текущей коллекции Point3DCol. Он такой же, как и GeneratePositions (), который вызывается в конструкторе, только с методом Positions.Clear () в начале. Он вызывается черезCalculateNoise ().

        private void ReplacePositions()
        {
            if(Positions.Count > 0)
            {
                Positions.Clear();
            }

            var column = 0;
            var row = 0;
            Point3D point = new Point3D();

            for (int i = 0; i < _terrainSize * _terrainSize; i++)
            {
                for (int j = 0; j < 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 & column
                column++;
                if (column % _terrainSize == 0)
                {
                    row++;
                }
                column %= _terrainSize;
            }
        }

        internal void CalculateNoise()
        {
            ReplacePositions();
            OnPropertyChanged("Positions");
        }

1 Ответ

0 голосов
/ 23 апреля 2019
public class GeometryTips : ViewModelBase
{
    #region " Private Fields "
    private int _terrainSize = 56;
    private Random random = new Random();
    #endregion

    #region " Public Properties "

    #region " MeshGeo "
    private MeshGeometry3D _MeshGeo;
    public MeshGeometry3D MeshGeo
    {
        get { return _MeshGeo; }
        set { this.Set(ref _MeshGeo, value); }
    }
    #endregion

    #endregion

    #region " Commands "

    #region " Create3DCommand "
    public RelayCommand Create3DCommand { get; private set; }
    private void Create3D()
    {
        for (int i = 0; i < _terrainSize * _terrainSize; i++)
        {
            Point3D point = new Point3D();
            point = MeshGeo.Positions[i];
            point.Y = random.Next(10) / 10.0;
            MeshGeo.Positions[i] = point;
        }
    }
    #endregion

    #endregion

    #region " Constructor "
    /// <summary>
    /// GeometryTips
    /// </summary>
    public GeometryTips()
    {
        this.Create3DCommand = new RelayCommand(Create3D);
        this._MeshGeo = new MeshGeometry3D();
        GeneratePositions();
        GenerateTriangleIndices();
    }
    #endregion

    #region " Private Functions "

    #region " GeneratePositions "
    /// <summary>
    /// GeneratePositions
    /// </summary>
    private void GeneratePositions()
    {

        var column = 0;
        var row = 0;
        Point3D point = new Point3D();

        for (int i = 0; i < _terrainSize * _terrainSize; i++)
        {
            for (int j = 0; j < 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;
            }
            _MeshGeo.Positions.Add(point);

            // Calculate next row & column
            column++;
            if (column % _terrainSize == 0)
            {
                row++;
            }
            column %= _terrainSize;
        }
    }
    #endregion

    #region " GenerateTriangleIndices "
    /// <summary>
    /// GenerateTriangleIndices
    /// </summary>
    private void GenerateTriangleIndices()
    {
        var value = 0;

        for (int i = 0; i < _terrainSize * _terrainSize - _terrainSize; i++)
        {
            for (int triangle = 0; triangle < 3; triangle++)
            {
                if (i % _terrainSize == 0)
                {
                    break;
                }
                if (triangle == 0)
                {
                    value = i;
                }
                else if (triangle == 1)
                {
                    value = i + triangle + _terrainSize - 2;
                }
                else if (triangle == 2)
                {
                    value = i + triangle + _terrainSize - 2;
                }
                _MeshGeo.TriangleIndices.Add(value);
            }
            for (int triangle = 0; triangle < 3; triangle++)
            {
                if (i > 0 && ((i + 1) % _terrainSize) == 0)
                {
                    break;
                }
                if (triangle == 0)
                {
                    value = i + triangle;
                }
                else if (triangle == 1)
                {
                    value = i + triangle + _terrainSize - 1;
                }
                else if (triangle == 2)
                {
                    value = i + triangle - 1;
                }
                _MeshGeo.TriangleIndices.Add(value);
            }
        }
    }
    #endregion

    #endregion
}

Я создал эту модель представления с помощью MVVM Light.

Я использую класс MeshGeometry3D для привязки.

Вот мой xaml:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="10"></ColumnDefinition>
        <ColumnDefinition></ColumnDefinition>
        <ColumnDefinition Width="10"></ColumnDefinition>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="10"></RowDefinition>
        <RowDefinition></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="10"></RowDefinition>
    </Grid.RowDefinitions>
    <Viewport3D Grid.Column="1" Grid.Row="1">
        <Viewport3D.Camera>
            <PerspectiveCamera x:Name="camera"/>
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup>
                    <DirectionalLight Direction="-1, -1, -3"/>
                    <GeometryModel3D Geometry="{Binding MeshGeo}">
                        <GeometryModel3D.Material>
                            <DiffuseMaterial Brush="White"/>
                        </GeometryModel3D.Material>
                    </GeometryModel3D>
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>
    <Button Grid.Column="1" Grid.Row="2" Content="Handle" Command="{Binding Create3DCommand}"></Button>
</Grid>

Этоработал на меня, надеюсь, это поможет ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...