相同的ScaleTransform3D用于不同的几何形状

时间:2017-03-31 08:31:28

标签: c# wpf data-binding 3d

我在后面的代码中创建我的几何模型,它们具有变换,具有数据绑定。 如果我为每个几何使用专用对象,那么它可以工作,如果我将相同的转换对象设置为所有几何,那么它什么都不做,并且还有三个错误消息"找不到用于绑定的源#33; RelativeSource FindAncestor,AncestorType = ..."对于调试输出中的ScaleX,ScaleY和ScaleZ。

有人可以解释这种行为吗?

<StackPanel Margin="20">
    <Slider x:Name="sldr" Margin="20"/>
    <local:ScaleViewPort Scale="{Binding Value, ElementName=sldr}" Width="400" Height="400"/>
</StackPanel>

<Viewport3D x:Class="WpfSandBox.ScaleViewPort"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Viewport3D.Camera>
        <OrthographicCamera x:Name="Cam" Position="200,200,10"  LookDirection="-200,-200,-10" UpDirection="0,0,1"/>
    </Viewport3D.Camera>
    <ModelVisual3D>
        <ModelVisual3D.Content>
            <Model3DGroup x:Name="modelGr">
                <DirectionalLight x:Name="light" Color="WhiteSmoke" Direction="-200,100,-200"/>
            </Model3DGroup>
        </ModelVisual3D.Content>
    </ModelVisual3D>
</Viewport3D>

namespace WpfSandBox
{
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;
    using System.Windows.Media.Media3D;
    public partial class ScaleViewPort : Viewport3D
    {
        public static readonly DependencyProperty ScaleProperty =
        DependencyProperty.Register(nameof(Scale), typeof(double), typeof(ScaleViewPort), null);
        public double Scale
        {
            get { return (double)GetValue(ScaleProperty); }
            set { SetValue(ScaleProperty, value); }
        }
        public ScaleViewPort()
        {
            InitializeComponent();

            var mat = new DiffuseMaterial(Brushes.Gray); mat.Freeze();
            var bMat = new DiffuseMaterial(Brushes.Red); bMat.Freeze();

            var bndng = new Binding(nameof(Scale));
            //bndng.Source = this; //This works also with same transformation object, thanks to Evk
            bndng.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);

            //Commented out does not work
            //var trans = new ScaleTransform3D();
            //BindingOperations.SetBinding(trans, ScaleTransform3D.ScaleXProperty, bndng);
            //BindingOperations.SetBinding(trans, ScaleTransform3D.ScaleYProperty, bndng);
            //BindingOperations.SetBinding(trans, ScaleTransform3D.ScaleZProperty, bndng);

            var pointsLists = new List<List<Point3D>>();
            var indexes = new List<int> { 0, 1, 2, 2, 3, 1, 1, 3, 0, 0, 3, 2 };
            for (int i = 0; i < 2; i++)
            {
                pointsLists.Add(new List<Point3D> { new Point3D(-2+i*4,0,0), new Point3D(2+i*4, 0, 0), new Point3D(2+i*4, 2, 0), new Point3D(0+i*4, 2, 4) });
            }

            for (int i = 0; i < pointsLists.Count; i++)
            {
                var geo = new MeshGeometry3D { Positions = new Point3DCollection(pointsLists[i]), TriangleIndices = new Int32Collection(indexes) };
                geo.Freeze();

                var geomod = new GeometryModel3D(geo, mat);
                geomod.BackMaterial = bMat;

                //geomod.Transform = trans; //Commented out does not work

                //this works
                geomod.Transform = new ScaleTransform3D();
                BindingOperations.SetBinding(geomod.Transform, ScaleTransform3D.ScaleXProperty, bndng);
                BindingOperations.SetBinding(geomod.Transform, ScaleTransform3D.ScaleYProperty, bndng);
                BindingOperations.SetBinding(geomod.Transform, ScaleTransform3D.ScaleZProperty, bndng);

                geomod.Geometry = geo;
                modelGr.Children.Add(geomod);
            }
        }
    }
}

0 个答案:

没有答案