Hi! Walter,
I’d like to change current pixel axis system(window left-top origin) to x,y coordinates like CAD(left-bottom origin).
My application is a kind of drawing tool for manufacturing simulation, which ouputs a neutral XML file for other tool(kind of CAD). Then, CAD tool can import the XML file.
So, I need to change location and origin information.
(See the attached picture)
First I should point out that one cannot just apply a ScaleTransform that would negate the Y coordinates. If you were to do so, everything would appear upside down, including your images and text.
But what you can do is data-bind the go:Node.Location using a converter that negates the Y value.
Here’s a sample application, named “NegativeY”, adapted from the StateChart sample:
[code]
<UserControl.Resources>
<local:NegativeYConverter x:Key=“theNegativeYConverter” />
<DataTemplate x:Key="StateTemplate">
<go:NodePanel Sizing="Auto"
go:Node.Location="{Binding Path=Data.Location, Mode=TwoWay,
Converter={StaticResource theNegativeYConverter}}"
go:Part.SelectionAdorned="True">
<go:NodeShape go:NodePanel.Figure="RoundedRectangle"
Fill="LightBlue" Stroke="Black" StrokeThickness="1"
go:Node.PortId=""
go:Node.LinkableFrom="True" go:Node.LinkableTo="True" />
<TextBlock Text="{Binding Path=Data.Key}" Margin="10"
HorizontalAlignment="Center" VerticalAlignment="Center" />
</go:NodePanel>
</DataTemplate>
</UserControl.Resources>
[/code] and the code-behind: [code]/* Copyright © Northwoods Software Corporation, 2008-2010. All Rights Reserved. */using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Xml.Linq;
using Northwoods.GoXam;
using Northwoods.GoXam.Model;
namespace NegativeY {
public partial class NegativeY : UserControl {
public NegativeY() {
InitializeComponent();
// create the diagram's data model
var model = new GraphLinksModel<State, String, String, Transition>();
model.NodesSource = new ObservableCollection<State>() {
new State() { Key="S1", Location=new Point(0, 0) },
new State() { Key="S2", Location=new Point(0, 100) },
new State() { Key="S3", Location=new Point(100, 100) },
};
model.LinksSource = new ObservableCollection<Transition>() {
new Transition() { From="S1", To="S2" },
new Transition() { From="S1", To="S3" },
};
model.Modifiable = true; // let the user modify the graph
model.HasUndoManager = true; // support undo/redo
myDiagram.Model = model;
}
private void Button_Click(object sender, RoutedEventArgs e) {
var model = myDiagram.Model as GraphLinksModel<State, String, String, Transition>;
XElement root = model.Save<State, Transition>("StateChart", "State", "Transition");
MessageBox.Show(root.ToString());
}
}
// This is used in the Node.Location binding in the NodeTemplate.
#if !SILVERLIGHT
[ValueConversion(typeof(Point), typeof(Point))]
#endif
public class NegativeYConverter : Converter {
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
Point p = (Point)value;
return new Point(p.X, -p.Y);
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
Point p = (Point)value;
return new Point(p.X, -p.Y);
}
}
// the data for each node; the predefined data class is enough for this sample
public class State : GraphLinksModelNodeData {
public State() {
this.Key = “State”;
}
}
// the data for each link
public class Transition : GraphLinksModelLinkData<String, String> { }
}[/code]