Helix 3D Toolkit-ZoomExtents方法调用的工作原理不同于通过手势激活ZoomExtents [英] Helix 3D Toolkit - ZoomExtents method call works different than activating ZoomExtents through gesture
问题描述
我一直在MVVM样式应用程序中的3D预览小窗口中工作...创建视图,然后设置其数据上下文.因此,似乎ZoomExtentsWhenLoaded ="True"似乎并不能帮助我完成所需的工作.我需要类似ZoomExtentsWhenDataContextChanges的东西.
I've been working on a small 3D preview window in a MVVM style application... The view is created then its data context is set. Therefore it seems that ZoomExtentsWhenLoaded="True" doesn't seem to help do what I need. I need something like, ZoomExtentsWhenDataContextChanges.
有趣的是,我发现如果我使用下面定义的鼠标手势,则可以物理上单击HelixViewport3D,它将执行ZoomExtents.
Interestingly, I've found that if I use a mouse gesture like the one defined below, I can physically click on the HelixViewport3D and it will perform a ZoomExtents.
HelixViewport3D.ZoomExtentsGesture = new MouseGesture(MouseAction.LeftDoubleClick);
但是,如果做这样的事情...
However, if do something like this...
HelixViewport3D.DataContextChanged += (o, e) => ResetCamera();
private void ResetCamera()
{
var dc = HelixViewport3D.DataContext as WellSurveyPlot3DViewModel;
HelixViewport3D.ResetCamera();
HelixViewport3D.Camera = dc.PerspectiveCamera;
HelixViewport3D.ZoomExtents();
}
视口会缩放,只是不会居中,就像使用鼠标手势激活ZoomExtents时一样.
The viewport does zoom, it just doesn't center itself, like it does when activating ZoomExtents when using the mouse gesture.
我尝试过ResetCamera以及其他几件事...处理视口周围和换出DataContext而不是每次创建一个新视口的标准方法是什么?
I tried ResetCamera, and several other things... What is the standard way of dealing with keeping a viewport around and swapping out the DataContext instead of creating a new one each time?
推荐答案
我使用附加属性修复了此问题.在注意到摄像头的工作原理之后,我通读了HelixViewport3D源代码并得到了这个想法.初始化控件后,似乎似乎无法通过属性绑定对默认摄像头进行更新.
I fixed this with an attached property. I read through the HelixViewport3D source code and got this idea, after noticing how the camera works. It seems an update to the default camera through a property binding doesn't really do anything after the control is initialized.
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属性.
In my view model I have to toggle my PreviewUpdateReZoom property.
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;
}
这现在可以正常工作,以便绘制到视口中的每个新项目都具有正确的相机设置并缩放到一定程度...
This now works such that every new item drawn into the viewport has the correct camera settings and zooms to extents...
这篇关于Helix 3D Toolkit-ZoomExtents方法调用的工作原理不同于通过手势激活ZoomExtents的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!