我用附加属性修复了这个问题。在注意到相机的工作原理后,我通读了 HelixViewport3D 源代码并得到了这个想法。在控件初始化后,通过属性绑定对默认相机的更新似乎并没有真正做任何事情。
public static class HelixViewport3DZoomExtent
{
private static readonly Type OwnerType = typeof(HelixViewport3DZoomExtent);
public static readonly DependencyProperty ZoomExtentsOnUpdateProperty = DependencyProperty.RegisterAttached("ZoomExtentsOnUpdate", typeof(bool), OwnerType, new PropertyMetadata(false, OnDataContextChanged));
public static bool GetZoomExtentsOnUpdate(DependencyObject obj)
{
return (bool)obj.GetValue(ZoomExtentsOnUpdateProperty);
}
public static void SetZoomExtentsOnUpdate(DependencyObject obj, bool value)
{
obj.SetValue(ZoomExtentsOnUpdateProperty, value);
}
private static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var viewport = d as HelixViewport3D;
if (viewport == null) return;
if (viewport.DataContext == null) return;
viewport.Camera = viewport.DefaultCamera;
viewport.ZoomExtents();
}
}
这是 Xaml
<Border BorderBrush="Black" BorderThickness="1">
<Grid>
<h:HelixViewport3D Name="HelixViewport3D"
PanGesture="LeftClick"
DataContext="{Binding PreviewPlot, UpdateSourceTrigger=PropertyChanged}"
DefaultCamera="{Binding PerspectiveCamera, UpdateSourceTrigger=PropertyChanged}"
services:HelixViewport3DZoomExtent.ZoomExtentsOnUpdate="{Binding RelativeSource={RelativeSource AncestorType={x:Type views:WellSurveyPlot3DPreview}},
Path=DataContext.PreviewUpdatedReZoom, UpdateSourceTrigger=PropertyChanged}">
<h:SunLight/>
<h:TubeVisual3D Path="{Binding TubePath}" Diameter="75" ThetaDiv="12" IsPathClosed="False" Fill="LightGray"/>
<h:GridLinesVisual3D Width="{Binding GridLength}" Length="{Binding GridLength}" MajorDistance="{Binding MajorGridLines}" Thickness="25"
MinorDistance="{Binding MajorGridLines, UpdateSourceTrigger=PropertyChanged}" LengthDirection="1,0,0" Normal="0,0,1"
Center="{Binding BottomPlaneCenter,UpdateSourceTrigger=PropertyChanged}" Fill="Red" />
<h:GridLinesVisual3D Width="{Binding GridLength}" Length="{Binding GridLength, UpdateSourceTrigger=PropertyChanged}" LengthDirection="0,0,1" Normal="1,0,0" Thickness="25"
MajorDistance="{Binding MajorGridLines}" MinorDistance="{Binding MajorGridLines}"
Center="{Binding BackLeftPlaneCenter, UpdateSourceTrigger=PropertyChanged}" Fill="Blue" />
<h:GridLinesVisual3D Width="{Binding GridLength}" Length="{Binding GridLength, UpdateSourceTrigger=PropertyChanged}" LengthDirection="1,0,0" Normal="0,1,0" Thickness="25"
MajorDistance="{Binding MajorGridLines}" MinorDistance="{Binding MajorGridLines}"
Center="{Binding BackRightPlaneCenter,UpdateSourceTrigger=PropertyChanged}" Fill="Green" />
</h:HelixViewport3D>
<Button Content="Open Well Viewer" HorizontalAlignment="Left" VerticalAlignment="Top" Command="{Binding OpenWindowCmd}"/>
</Grid>
</Border>
在我的视图模型中,我必须切换我的 PreviewUpdateReZoom 属性。
private void LoadSurveyPoints(List<WellSurveyPointCalculated> surveyPoints)
{
_coordinatesCalculator = _calcGlobalCoordsFactory.Create(surveyPoints);
_wellXyzCoordinates = _coordinatesCalculator.PlotGlobalCoordinates(100).ToList();
PreviewPlot = WellSurveyPlot3DViewModel();
PreviewUpdatedReZoom = false;//Toggle true false to send property changed and get attached property to fire.
PreviewUpdatedReZoom = true;
}
现在,这可以使绘制到视口中的每个新项目都具有正确的相机设置并缩放到范围...