【发布时间】:2019-04-23 15:16:29
【问题描述】:
你好,
我的 Point3DCollection 的生成工作正常,并且我在 Viewport3D (https://imgur.com/5Hzitw2) 中获得了网格,但是即使调用了我的 ViewModel 中的 OnPropertyChanged 方法,calculateNoise() 也不会更新我在 Viewport3D 中的绑定位置。我在这里做错了什么?
提前致谢, 康斯特IT
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>
视口视图模型:
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
}
替换当前 Point3DCollection 的代码。它与在构造函数中调用的 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");
}
【问题讨论】:
-
这个问题太宽泛了......请更具体一点,您在哪里尝试过什么?
-
将 Point3DCollection 公开为实现 INotifyPropertyChanged 的视图模型的属性。我们称该属性为
Points。在 XAML 中适当地绑定它。当您更改集合中的某个点时,调用PropertyChanged(nameof(Points))以便绑定知道它需要更新目标属性。 -
嘿@Ed Plunkett,感谢您的建议。不幸的是,这不起作用:( XAML 中的绑定:
Positions="{Binding Points, UpdateSourceTrigger=PropertyChanged}"和我在 viewModel 中调用的方法实际上调用了 INotifyPropertyChanged 接口的 OnPropertyChanged 方法。但不知何故,它不会更新绑定到 Viewport3D 的 Point3DCollection -
1) 在您阅读并理解其中的文档之前,请不要添加
UpdateSourceTrigger=PropertyChanged。 2)请显示不起作用的代码。如果绑定完全有效,它应该是一个简单的修复。 -
嘿@Ed Plunkett,我更改了通用问题并更新了代码。现在有 XAML 部分,我猜这很好,而 viewModel 出了问题。
标签: wpf mvvm data-binding