我在后面的代码中创建我的几何模型,它们具有变换,具有数据绑定。 如果我为每个几何使用专用对象,那么它可以工作,如果我将相同的转换对象设置为所有几何,那么它什么都不做,并且还有三个错误消息"找不到用于绑定的源#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);
}
}
}
}