2

私はMVVMスタイルのアプリケーションで小さな3Dプレビューウィンドウに取り組んできました...ビューが作成され、そのデータコンテキストが設定されます。したがって、 ZoomExtentsWhenLoaded="True" は、必要なことを行うのに役立たないようです。ZoomExtentsWhenDataContextChanges のようなものが必要です。

興味深いことに、以下に定義されているようなマウス ジェスチャを使用すると、HelixViewport3D を物理的にクリックして、ZoomExtents を実行できることがわかりました。

HelixViewport3D.ZoomExtentsGesture = new MouseGesture(MouseAction.LeftDoubleClick);

しかし、このようなことをすると...

HelixViewport3D.DataContextChanged += (o, e) => ResetCamera();

private void ResetCamera()
{
    var dc = HelixViewport3D.DataContext as WellSurveyPlot3DViewModel;
    HelixViewport3D.ResetCamera();
    HelixViewport3D.Camera = dc.PerspectiveCamera;
    HelixViewport3D.ZoomExtents();
}

ビューポートはズームしますが、マウス ジェスチャを使用して ZoomExtents を有効にしたときのように、中央に配置されません。

私は ResetCamera と他のいくつかのことを試しました...毎回新しいビューポートを作成する代わりに、ビューポートを保持し、DataContext を交換する標準的な方法は何ですか?

4

1 に答える 1

1

これを添付プロパティで修正しました。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;
        }

これは、ビューポートに描画されるすべての新しいアイテムが正しいカメラ設定を持ち、範囲にズームするように機能するようになりました...

于 2014-09-14T18:25:16.417 に答える