Silverlight 4 WriteableBitmap ScaleTransform Exception but was working in v3 - silverlight

I am getting the following exception for code that used to work in silverlight 3 but has stopped working since upgrading to silverlight 4:
System.AccessViolationException was unhandled
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
var OpenFileDialog = new OpenFileDialog();
OpenFileDialog.Filter = "*.jpg|*.jpg";
if (OpenFileDialog.ShowDialog() == true)
{
var file = OpenFileDialog.Files.ToArray()[0];
ScaleStreamAsBitmap(file.OpenRead(), 200);
}
}
public static WriteableBitmap ScaleStreamAsBitmap(Stream file, int maxEdgeLength)
{
file.Position = 0;
var src = new BitmapImage();
var uiElement = new System.Windows.Controls.Image();
WriteableBitmap b = null;
var t = new ScaleTransform();
src.SetSource(file);
uiElement.Source = src;
//force render
uiElement.Effect = new DropShadowEffect() { ShadowDepth = 0, BlurRadius = 0 }; ;
//calc scale
double scaleX = 1;
double scaleY = 1;
if (src.PixelWidth > maxEdgeLength)
scaleX = ((double)maxEdgeLength) / src.PixelWidth;
if (src.PixelHeight > maxEdgeLength)
scaleY = ((double)maxEdgeLength) / src.PixelHeight;
double scale = Math.Min(scaleX, scaleY);
t.ScaleX = scale;
t.ScaleY = scale;
b = new WriteableBitmap(uiElement, t);
return b;
}
}
}
Thanks

I had the same problem and I succeeded to resolve it!
b=new new WriteableBitmap(0, 0);
b.SetSource(file);
b.Render( new Image() { Source = src, Effect = new DropShadowEffect() { ShadowDepth = 0, BlurRadius = 0 } }, new ScaleTransform() { ScaleX = scaleX , ScaleY = scaleY });
And you can remove :uiElement and file.Position!

Related

WPF - Helix Toolkit Auto Rotation

I have been researching this over the last week - 2 weeks and I have been unable to find a solution. I am loading a 3D Model from an STL file and attempting to rotate the 3D model automatically around 1 axis. The idea would be something like a slow-moving animation that displays a 360-degree view around the Y-axis of the model.
XAML:
<Grid>
<StackPanel x:Name="myViewPort">
<helix:HelixViewport3D x:Name="viewPort3d" ZoomExtentsWhenLoaded="true" RotateAroundMouseDownPoint="true" CameraRotationMode="Turntable" Height="1000" ShowViewCube="false">
<helix:DefaultLights/>
<ModelVisual3D x:Name="visualModel"/>
</helix:HelixViewport3D>
</StackPanel>
</Grid>
C#:
public void load3dModel()
{
StLReader stlReader = new StLReader();
Model3DGroup MyModel = stlReader.Read(MODEL_PATH);
/* Auto Rotate Here */
System.Windows.Media.Media3D.Material mat = MaterialHelper.CreateMaterial(new SolidColorBrush(Color.FromRgb(255, 255, 255)));
foreach (System.Windows.Media.Media3D.GeometryModel3D geometryModel in MyModel.Children)
{
geometryModel.Material = mat;
geometryModel.BackMaterial = mat;
}
visualModel.Content = MyModel;
}
The tricky part about this is I need to be able to rotate the model using CODE ONLY. The models generated can be one of the hundreds, and it will depend on the application for what the model will be... So the code needs to be able to handle rotating around the same axis, I can guarantee when the 3D model is exported to the STL file it will be flat along the X-axis.
--- UPDATE ---
Attempted Rotation via Storyboard:
public void load3dModel()
{
StLReader stlReader = new StLReader();
Model3DGroup MyModel = stlReader.Read(MODEL_PATH);
System.Windows.Media.Media3D.Material mat = MaterialHelper.CreateMaterial(new SolidColorBrush(Color.FromRgb(255, 255, 255)));
foreach (System.Windows.Media.Media3D.GeometryModel3D geometryModel in MyModel.Children)
{
geometryModel.Material = mat;
geometryModel.BackMaterial = mat;
}
visualModel.Content = MyModel;
/* Auto Rotate Here */
GeometryModel3D geoModel = new GeometryModel3D()
{
Transform = new RotateTransform3D()
{
Rotation = new AxisAngleRotation3D()
{
Axis = new Vector3D(0, 1, 0),
Angle = 0
}
}
};
MyModel.Children.Add(geoModel);
var Rotation3DAnimation = new Rotation3DAnimation();
var FromAxis = new AxisAngleRotation3D()
{
Axis = new Vector3D(0, 1, 0),
Angle = 0
};
var ToAxis = new AxisAngleRotation3D()
{
Axis = new Vector3D(0, 1, 0),
Angle = 359
};
Rotation3DAnimation.From = FromAxis;
Rotation3DAnimation.To = ToAxis;
Rotation3DAnimation.Duration = Duration.Forever; //ADDED DURATION, Still did not work!
var rotateStoryboard = new Storyboard
{
Duration = new Timespan(0, 0, 12),
RepeatBehavior = RepeatBehavior.Forever,
};
Storyboard.SetTarget(Rotation3DAnimation, geoModel.Transform);
Storyboard.SetTargetProperty(Rotation3DAnimation, new PropertyPath("Rotation"));
rotateStoryboard.Children.Add(Rotation3DAnimation);
rotateStoryboard.Begin();
}
This did not work... Nothing changed?
Thanks!
I am not sure if I understood correctly what you are trying to accomplish so let me know if I misunderstood:
In the code you showed, you are loading several GeometryModel3D so are you trying to make them all rotate or just one ?
One way you could make it rotate is via the Transform property of the GeometryModel3D.
You will have to set up a DispatcherTimer and update the angle of the rotation on every Tick:
I made an example based on what you provided where I make one 3D model rotate:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Load3dModel();
this.timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(10) };
this.timer.Tick += Timer_Tick;
this.timer.Start();
}
/// <summary>
/// Change the rotation
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Timer_Tick(object sender, EventArgs e)
{
if (this.angle >= 360)
{
this.angle = 0;
}
else
{
//Nothing to do
}
this.angle = this.angle + 0.25;
//You can adapt the code if you have many children
GeometryModel3D geometryModel3D = (GeometryModel3D)((Model3DGroup)visualModel.Content).Children.First();
if (geometryModel3D.Transform is RotateTransform3D rotateTransform3 && rotateTransform3.Rotation is AxisAngleRotation3D rotation)
{
rotation.Angle = this.angle;
}
else
{
///Initialize the Transform (I didn't do it in my example but you could do this initialization in <see Load3dModel/>)
geometryModel3D.Transform = new RotateTransform3D()
{
Rotation = new AxisAngleRotation3D()
{
Axis = new Vector3D(0, 1, 0),
Angle = this.angle,
}
};
}
}
private DispatcherTimer timer;
public void Load3dModel()
{
StLReader stlReader = new StLReader();
/*
Model3DGroup MyModel = stlReader.Read(OrLoadFromPath));
*/
Model3DGroup myModel = new Model3DGroup();
// Create a mesh builder and add a box to it
var meshBuilder = new MeshBuilder(false, false);
meshBuilder.AddBox(new Point3D(0, 0, 1), 1, 2, 0.5);
meshBuilder.AddBox(new Rect3D(0, 0, 1.2, 0.5, 1, 0.4));
// Create a mesh from the builder (and freeze it)
var mesh = meshBuilder.ToMesh(true);
// Add 3 models to the group (using the same mesh, that's why we had to freeze it)
myModel.Children.Add(new GeometryModel3D { Geometry = mesh});
myModel.Children.Add(new GeometryModel3D { Geometry = mesh, Transform = new TranslateTransform3D(-2, 0, 0)});
myModel.Children.Add(new GeometryModel3D { Geometry = mesh, Transform = new TranslateTransform3D(2, 0, 0)});
System.Windows.Media.Media3D.Material mat = MaterialHelper.CreateMaterial(new SolidColorBrush(Color.FromRgb(255, 255, 255)));
foreach (System.Windows.Media.Media3D.GeometryModel3D geometryModel in myModel.Children)
{
geometryModel.Material = mat;
geometryModel.BackMaterial = mat;
}
visualModel.Content = myModel;
}
private double angle = 0;
}
The rotation was pretty smooth on my end with those parameters but you will have to test/adapt it on your application.

How to draw a line between two WPF controls using dependency properties?

I need to draw a line connecting two WPF controls. I have defined a dependency property in my Node objects so if the Node is moved the line still connect the objects.
I have the following example but I'm unable to get it working.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
Node node1 = new Node(myCanvas) { Width = 50, Height = 50 };
Node node2 = new Node(myCanvas) { Width = 50, Height = 50 };
Canvas.SetLeft(node1, 0);
Canvas.SetLeft(node2, 200);
Canvas.SetTop(node1, 0);
Canvas.SetTop(node2, 0);
myCanvas.Children.Add(node1);
myCanvas.Children.Add(node2);
Connector conn = new Connector();
conn.Source = node1.AnchorPoint;
conn.Destination = node2.AnchorPoint;
myCanvas.Children.Add(conn);
}
}
class Node : Control
{
public static readonly DependencyProperty AnchorPointProperty =
DependencyProperty.Register(
"AnchorPoint", typeof(Point), typeof(Node),
new FrameworkPropertyMetadata(new Point(0, 0),
FrameworkPropertyMetadataOptions.AffectsMeasure));
public Point AnchorPoint
{
get { return (Point)GetValue(AnchorPointProperty); }
set { SetValue(AnchorPointProperty, value); }
}
private Canvas mCanvas;
public Node(Canvas canvas)
{
mCanvas = canvas;
this.LayoutUpdated += Node_LayoutUpdated;
}
void Node_LayoutUpdated(object sender, EventArgs e)
{
Size size = RenderSize;
Point ofs = new Point(size.Width / 2, size.Height / 2);
AnchorPoint = TransformToVisual(this.mCanvas).Transform(ofs);
}
protected override void OnRender(DrawingContext drawingContext)
{
drawingContext.DrawEllipse(
Brushes.Red,
null,
new Point(Width / 2, Height / 2), Width / 2, Height / 2);
}
}
public sealed class Connector : UserControl
{
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register(
"Source", typeof(Point), typeof(Connector),
new FrameworkPropertyMetadata(default(Point)));
public Point Source {
get { return (Point)this.GetValue(SourceProperty); }
set { this.SetValue(SourceProperty, value); }
}
public static readonly DependencyProperty DestinationProperty =
DependencyProperty.Register(
"Destination", typeof(Point), typeof(Connector),
new FrameworkPropertyMetadata(default(Point)));
public Point Destination {
get { return (Point)this.GetValue(DestinationProperty); }
set { this.SetValue(DestinationProperty, value); }
}
public Connector()
{
LineSegment segment = new LineSegment(default(Point), true);
PathFigure figure = new PathFigure(default(Point), new[] { segment }, false);
PathGeometry geometry = new PathGeometry(new[] { figure });
BindingBase sourceBinding =
new Binding { Source = this, Path = new PropertyPath(SourceProperty) };
BindingBase destinationBinding =
new Binding { Source = this, Path = new PropertyPath(DestinationProperty) };
BindingOperations.SetBinding(
figure, PathFigure.StartPointProperty, sourceBinding);
BindingOperations.SetBinding(
segment, LineSegment.PointProperty, destinationBinding);
Content = new Path
{
Data = geometry,
StrokeThickness = 5,
Stroke = Brushes.White,
MinWidth = 1,
MinHeight = 1
};
}
}
All you have to do to make your example work is to bind conn.Source and .Destination to the nodes' AnchorPoints, or else the Connector just get the AnchorPoints' initial values (0,0), and doesn't listen for further changes:
...
Connector conn = new Connector();
//conn.Source = node1.AnchorPoint;
conn.SetBinding(Connector.SourceProperty,
new Binding()
{
Source = node1,
Path = new PropertyPath(Node.AnchorPointProperty)
});
//conn.Destination = node2.AnchorPoint;
conn.SetBinding(Connector.DestinationProperty,
new Binding()
{
Source = node2,
Path = new PropertyPath(Node.AnchorPointProperty)
});
myCanvas.Children.Add(conn);

Is a dashed border around a selected text/image element possible in Silverlight?

I have an image editor I'm developing in silverlight which has multiple text and image elements on one canvas, that are draggable etc. I need feedback for the user to highlight the selected element when it is clicked on by the user and highlight a different element instead if another is clicked. I think I should do this with a dashed border around the element, but I don't know if it's possible.
Below is my code relating to the elements -
Project.cs
namespace ImageEditor.Client.BLL
{
public class Project : INotifyPropertyChanged
{
private int numberOfElements;
#region Properties
private ObservableCollection<FrameworkElement> elements;
public ObservableCollection<FrameworkElement> Elements
{
get { return elements; }
set
{
elements = value;
NotifyPropertyChanged("Elements");
}
}
private FrameworkElement selectedElement;
public FrameworkElement SelectedElement
{
get { return selectedElement; }
set
{
selectedElement = value;
NotifyPropertyChanged("SelectedElement");
}
}
private TextBlock selectedTextElement;
public TextBlock SelectedTextElement
{
get { return selectedTextElement; }
set
{
selectedTextElement = value;
NotifyPropertyChanged("SelectedTextElement");
}
}
private Image selectedImageElement;
public Image SelectedImageElement
{
get { return selectedImageElement; }
set
{
selectedImageElement = value;
NotifyPropertyChanged("SelectedImageElement");
}
}
#endregion
#region Methods
private void AddTextElement(object param)
{
TextBlock textBlock = new TextBlock();
textBlock.Text = "New Text";
textBlock.Foreground = new SolidColorBrush(Colors.Gray);
textBlock.FontSize = 25;
textBlock.FontFamily = new FontFamily("Arial");
textBlock.Cursor = Cursors.Hand;
textBlock.Tag = null;
AddDraggingBehavior(textBlock);
textBlock.MouseLeftButtonUp += element_MouseLeftButtonUp;
this.Elements.Add(textBlock);
numberOfElements++;
this.SelectedElement = textBlock;
this.selectedTextElement = textBlock;
}
private BitmapImage GetImageFromLocalMachine(out bool? success, out string fileName)
{
OpenFileDialog dialog = new OpenFileDialog()
{
Filter = "Image Files (*.bmp;*.jpg;*.gif;*.png;)|*.bmp;*.jpg;*.gif;*.png;",
Multiselect = false
};
success = dialog.ShowDialog();
if (success == true)
{
fileName = dialog.File.Name;
FileStream stream = dialog.File.OpenRead();
byte[] data;
BitmapImage imageSource = new BitmapImage();
using (FileStream fileStream = stream)
{
imageSource.SetSource(fileStream);
data = new byte[fileStream.Length];
fileStream.Read(data, 0, data.Length);
fileStream.Flush();
fileStream.Close();
}
return imageSource;
}
else
{
fileName = string.Empty;
return new BitmapImage();
}
}
private void AddImageElement(object param)
{
bool? gotImage;
string fileName;
BitmapImage imageSource = GetImageFromLocalMachine(out gotImage, out fileName);
if (gotImage == true)
{
Image image = new Image();
image.Name = fileName;
image.Source = imageSource;
image.Height = imageSource.PixelHeight;
image.Width = imageSource.PixelWidth;
image.MaxHeight = imageSource.PixelHeight;
image.MaxWidth = imageSource.PixelWidth;
image.Cursor = Cursors.Hand;
image.Tag = null;
AddDraggingBehavior(image);
image.MouseLeftButtonUp += element_MouseLeftButtonUp;
this.Elements.Add(image);
numberOfElements++;
this.SelectedElement = image;
this.SelectedImageElement = image;
}
}
private void OrderElements()
{
var elList = (from element in this.Elements
orderby element.GetValue(Canvas.ZIndexProperty)
select element).ToList<FrameworkElement>();
for (int i = 0; i < elList.Count; i++)
{
FrameworkElement fe = elList[i];
fe.SetValue(Canvas.ZIndexProperty, i);
}
this.Elements = new ObservableCollection<FrameworkElement>(elList);
}
public void element_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
this.SelectedElement = sender as FrameworkElement;
if (sender is TextBlock)
{
this.SelectedTextElement = sender as TextBlock;
FadeOut(this.SelectedTextElement);
}
else if (sender is Image)
{
this.SelectedImageElement = sender as Image;
FadeOut(this.SelectedImageElement);
}
}
#endregion
More than needed there but you get a good idea of how it all works from that. How might I go about it? I'm still pretty new to silverlight
Edit:
This is my start attempt at a DashBorder Method, wherein I'm trying to make a rectangle the same dimensions as the selected element which will go around the element
public static void DashBorder(FrameworkElement element)
{
Rectangle rect = new Rectangle();
rect.Stroke = new SolidColorBrush(Colors.Black);
rect.Width=element.Width;
rect.Height=element.Height;
rect.StrokeDashArray = new DoubleCollection() { 2, 2 };
}
It appears to do nothing and isn't what I want to do anyway. Is there no way to make a dash border on a FrameworkElement directly?
I don't know how, but google does.
You can use the StrokeDashArray to achieve the desired effect,
example:
<Rectangle Canvas.Left="10" Canvas.Top="10" Width="100" Height="100"
Stroke="Black" StrokeDashArray="10, 2"/>
The first number in StrokeDashArray is the length of the dash, the
second number is the length of the gap. You can repeat the dash gap
pairs to generate different patterns.
Edit:
To do this in code create a rectangle and set it's StrokeDashArray property like this (code untested):
Rectangle rect = new Rectangle();
rect.StrokeThickness = 1;
double[] dashArray = new double[2];
dashArray[0] = 2;
dashArray[1] = 4;
rect.StrokeDashArray = dashArray;

Silverlight cannot update property after animation runs

Im trying to create a simple pan and zoom app using silverlight 4, but Im having trouble updating the TranslateTransform and ScaleTransform properties after I run an animation on them.
I have tried to set the FillBehaviour to Stop, with no success.
Here is the code that I have:
<Canvas x:Name="LayoutRoot" Background="White" Width="800" Height="600">
<Canvas x:Name="PanningCanvas" Height="600" Width="800">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="CanvasScale"/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform x:Name="CanvasTransform"/>
</TransformGroup>
</Canvas.RenderTransform>
<Rectangle x:Name="MovingRect" Fill="#FF834040" Height="209" Canvas.Left="219" Stroke="#FF500505" Canvas.Top="220" Width="329" StrokeThickness="2"/>
</Canvas>
<Button Content="Animate" Width="107" Canvas.Left="38" Canvas.Top="46" ClickMode="Press" Click="Button_Click"/>
</Canvas>
And here is the C# behind it all (slightly abbreviated)
public partial class MainPage : UserControl
{
private ManipulationProcessor2D manipulationProcessor;
public MainPage()
{
InitializeComponent();
this.manipulationProcessor = new ManipulationProcessor2D(Manipulations2D.Translate | Manipulations2D.Scale);
this.manipulationProcessor.Delta += OnManipulationDelta;
Touch.FrameReported += OnCapturedTouchReported;
}
private void OnManipulationDelta(object sender, Manipulation2DDeltaEventArgs e)
{
float zoomVal = e.Delta.ScaleX;
Point pinchPoint = new Point(e.OriginX, e.OriginY);
float xTranslation = e.Delta.TranslationX;
float yTranslation = e.Delta.TranslationY;
if (zoomVal != 1.0)
{
Zoom(zoomVal, PanningCanvas.RenderTransform.Inverse.Transform(pinchPoint), pinchPoint, xTranslation, yTranslation, true);
}
else if (xTranslation != 0 || yTranslation != 0)
{
Translate(xTranslation, yTranslation);
}
}
public void Zoom(double zoom, Point pinchPosition, Point physicalPosition, float xTranslation, float yTranslation, bool isFinger)
{
if (isFinger)
{
CanvasScale.ScaleX = CanvasScale.ScaleX * zoom;
CanvasScale.ScaleY = CanvasScale.ScaleY * zoom;
CanvasTransform.X = -1 * (pinchPosition.X * CanvasScale.ScaleX - physicalPosition.X);
CanvasTransform.Y = -1 * (pinchPosition.Y * CanvasScale.ScaleY - physicalPosition.Y);
}
else
{
CanvasScale.ScaleX = CanvasScale.ScaleX + zoom;
CanvasScale.ScaleY = CanvasScale.ScaleY + zoom;
}
}
private void Translate(float xTranslation, float yTranslation)
{
CanvasTransform.X += xTranslation;
CanvasTransform.Y += yTranslation;
}
private void OnCapturedTouchReported(object sender, TouchFrameEventArgs e)
{
//..removed..//
// process manipulations
this.manipulationProcessor.ProcessManipulators(DateTime.UtcNow.Ticks,manipulators);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AnimatePosition(new Point(400, 300), 1);
AnimateScale(1.2, 1);
}
private Storyboard translateStoryboard = new Storyboard();
private Storyboard scaleStoryboard = new Storyboard();
public void AnimatePosition(Point destinationPoint, double lengthOfAnimation)
{
Point offset = new Point(destinationPoint.X, destinationPoint.Y);
var translationAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.X };
translateStoryboard.Children.Add(translationAnimationX);
Storyboard.SetTargetProperty(translationAnimationX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
var translationAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.Y };
translateStoryboard.Children.Add(translationAnimationY);
Storyboard.SetTargetProperty(translationAnimationY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)"));
Storyboard.SetTarget(translateStoryboard, PanningCanvas);
translateStoryboard.Begin();
}
public void AnimateScale( double scale, double lengthOfAnimation)
{
var scaleAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = scale };
scaleStoryboard.Children.Add(scaleAnimationX);
Storyboard.SetTargetProperty(scaleAnimationX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));
var scaleAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = scale };
scaleStoryboard.Children.Add(scaleAnimationY);
Storyboard.SetTargetProperty(scaleAnimationY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));
Storyboard.SetTarget(scaleStoryboard, PanningCanvas);
scaleStoryboard.Begin();
}
}
The issue is that after I click the button, I cannot translate or zoom anymore...
please help!
Mark
Ok, so I got it working, but I dont know why.
Changing the animation to work like this:
Storyboard translateStoryboard = new Storyboard();
Point offset = new Point(destinationPoint.X, destinationPoint.Y);
var translationAnimationX = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.X };
var translationAnimationY = new DoubleAnimation() { SpeedRatio = 1, Duration = new Duration(TimeSpan.FromSeconds(lengthOfAnimation)), To = offset.Y };
Storyboard.SetTargetProperty(translationAnimationX, new PropertyPath("X"));
Storyboard.SetTargetProperty(translationAnimationY, new PropertyPath("Y"));
Storyboard.SetTargetName(translationAnimationX, "CanvasTransform");
Storyboard.SetTargetName(translationAnimationY, "CanvasTransform");
translateStoryboard.Children.Add(translationAnimationX);
translateStoryboard.Children.Add(translationAnimationY);
translateStoryboard.Begin();
Did the trick, but I dont know why...
Can someone please explain it to me?

Problem adding Viewport2DVisual3D from Code

I'm trying to add a Viewport2DVisual3D to a Viewport3D in code, but the visual isn't showing up. Any help understanding why not would be appreciated. The following is the code for the main window.
Is it sufficient to just add the Viewport2DVisual3D to the children of the Viewport3D in order for it to be rendered?
public partial class Window1 : System.Windows.Window
{
public Window1()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(temp);
}
public void temp(object sender, RoutedEventArgs e)
{
Viewport2DVisual3D test = new Viewport2DVisual3D();
MeshGeometry3D testGeometry = new MeshGeometry3D();
Vector3D CameraLookDirection = Main_Target_CameraOR20.LookDirection;
// Calculate the Positions based on the Camera
Point3DCollection myPoint3DCollection = new Point3DCollection();
myPoint3DCollection.Add(new Point3D(-1, 1, 0));
myPoint3DCollection.Add(new Point3D(-1, -1, 0));
myPoint3DCollection.Add(new Point3D(1, -1, 0));
myPoint3DCollection.Add(new Point3D(1, 1, 0));
testGeometry.Positions = myPoint3DCollection;
PointCollection myPointCollection = new PointCollection();
myPointCollection.Add(new Point(0, 0));
myPointCollection.Add(new Point(0, 1));
myPointCollection.Add(new Point(1, 1));
myPointCollection.Add(new Point(1, 0));
testGeometry.TextureCoordinates = myPointCollection;
Int32Collection triangleIndicesCollection = new Int32Collection();
triangleIndicesCollection.Add(0);
triangleIndicesCollection.Add(1);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(2);
triangleIndicesCollection.Add(3);
triangleIndicesCollection.Add(0);
testGeometry.TriangleIndices = triangleIndicesCollection;
DiffuseMaterial myDiffuseMaterial = new DiffuseMaterial(Brushes.White);
Viewport2DVisual3D.SetIsVisualHostMaterial(myDiffuseMaterial, true);
Transform3DGroup myTransform3DGroup = new Transform3DGroup();
ScaleTransform3D myScaleTransform3D = new ScaleTransform3D();
myScaleTransform3D.ScaleX = 2;
myScaleTransform3D.ScaleY = 2;
myScaleTransform3D.ScaleZ = 2;
TranslateTransform3D myTranslateTransform3D = new TranslateTransform3D();
myTranslateTransform3D.OffsetX = -27;
myTranslateTransform3D.OffsetY = 13;
myTranslateTransform3D.OffsetZ = 6;
RotateTransform3D rotateTransform = new RotateTransform3D()
{
Rotation = new AxisAngleRotation3D
{
Angle = -50,
Axis = new Vector3D(0, 1, 0)
}
};
myTransform3DGroup.Children.Add(myTranslateTransform3D);
myTransform3DGroup.Children.Add(myScaleTransform3D);
myTransform3DGroup.Children.Add(rotateTransform);
test.Transform = myTransform3DGroup;
Button myButton = new Button();
myButton.Content = "Test Button";
test.Material = myDiffuseMaterial;
test.Geometry = testGeometry;
test.Visual = myButton;
ZAM3DViewport3D.Children.Add(test);
}
}
It turns out that the problem was the Offset value. So, it is sufficient to add the child to the Viewport3D to have it render. Cheers

Resources