How can I change axis system?

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]