更改WPF画布的坐标系 [英] Change the coordinate system of a Canvas in WPF

查看:209
本文介绍了更改WPF画布的坐标系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在写一个使用定位元素的帆布映射应用程序。对于每个元素我要转换编程元素的纬度/龙在画布上'坐标,然后设置Canvas.Top和Canvas.Left属性。



如果我有一个360x180帆布,我可以转换在画布上的坐标去从-180到180,而不是0到360在X轴和90至-90而不是0到180的Y轴



缩放要求:




  • 画布可以是任意大小,因此如果是360x180或5000x100应该仍然工作

  • 的纬度/长区并不总是(-90,-180)×(90,180),它可以是任何东西(即(5,-175)×(89,-174))

  • 元素,如的PathGeometry这是一点基础的,而不是基于Canvas.Top/Left需要工作。


< DIV CLASS =h2_lin>解决方案

下面是一个全XAML的解决方案。好了,主要是XAML,因为你必须拥有的IValueConverter代码。所以:创建一个新的WPF项目并添加一个类到它。类是MultiplyConverter:

 命名空间YourProject 
{
公共类MultiplyConverter:System.Windows.Data。的IValueConverter
{
公共对象转换(对象的值,System.Type的TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
{
返回AsDouble(值)* AsDouble(参数);
}
双AsDouble(对象的值)
{
VAR valueText =值串;
如果(valueText!= NULL)
返回double.Parse(valueText);
,否则
回报(双)值;
}

公共对象ConvertBack(对象的值,System.Type的TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
{
抛出新System.NotSupportedException( );
}
}
}



然后使用XAML为您窗口。现在你应该可以看到就在你的XAML预览窗口中的结果。



修改:您可以将您的帆布另一个Canvas中修复背景问题。很怪,但它的作品。此外,我添加了翻转Y轴,使Y正达和负面的跌幅为ScaleTransform。仔细注意哪些名字去的地方:

 <帆布NAME =画布的背景=莫卡辛> 
<帆布NAME =innerCanvas>
< Canvas.RenderTransform>
<&的TransformGroup GT;
< TranslateTransform X:NAME =翻译>
< TranslateTransform.X>
<绑定的ElementName =画布PATH =ActualWidth的
转换器={StaticResource的mu​​ltiplyConverter}ConverterParameter =0.5/>
< /TranslateTransform.X>
< TranslateTransform.Y>
<绑定的ElementName =画布PATH =的ActualHeight
转换器={StaticResource的mu​​ltiplyConverter}ConverterParameter =0.5/>
< /TranslateTransform.Y>
< / TranslateTransform>
< ScaleTransform的ScaleX =1的scaleY = - 1的centerX ={绑定的ElementName =翻译,路径= X}
CenterY ={绑定的ElementName =翻译,路径= Y} />
< /&的TransformGroup GT;
< /Canvas.RenderTransform>
<矩形Canvas.Top = - 50Canvas.Left = - 50HEIGHT =100WIDTH =200填充=蓝/>
<矩形Canvas.Top =0Canvas.Left =0HEIGHT =200WIDTH =100填充=绿色/>
<矩形Canvas.Top = - 25Canvas.Left = - 25HEIGHT =50WIDTH =50填充=暗粉红/>
< /帆布>
< /帆布>



至于你需要不同范围的新要求,更复杂的ValueConverter可能会做的伎俩。


I'm writing a mapping app that uses a Canvas for positioning elements. For each element I have to programatically convert element's Lat/Long to the canvas' coordinate, then set the Canvas.Top and Canvas.Left properties.

If I had a 360x180 Canvas, can I convert the coordinates on the canvas to go from -180 to 180 rather than 0 to 360 on the X axis and 90 to -90 rather than 0 to 180 on the Y axis?

Scaling requirements:

  • The canvas can be any size, so should still work if it's 360x180 or 5000x100.
  • The Lat/Long area may not always be (-90,-180)x(90,180), it could be anything (ie (5,-175)x(89,-174)).
  • Elements such as PathGeometry which are point base, rather than Canvas.Top/Left based need to work.

解决方案

Here's an all-XAML solution. Well, mostly XAML, because you have to have the IValueConverter in code. So: Create a new WPF project and add a class to it. The class is MultiplyConverter:

namespace YourProject
{
    public class MultiplyConverter : System.Windows.Data.IValueConverter
    {
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return AsDouble(value)* AsDouble(parameter);
        }
        double AsDouble(object value)
        {
            var valueText = value as string;
            if (valueText != null)
                return double.Parse(valueText);
            else
                return (double)value;
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new System.NotSupportedException();
        }
    }
}

Then use this XAML for your Window. Now you should see the results right in your XAML preview window.

EDIT: You can fix the Background problem by putting your Canvas inside another Canvas. Kind of weird, but it works. In addition, I've added a ScaleTransform which flips the Y-axis so that positive Y is up and negative is down. Note carefully which Names go where:

<Canvas Name="canvas" Background="Moccasin">
    <Canvas Name="innerCanvas">
        <Canvas.RenderTransform>
            <TransformGroup>
                <TranslateTransform x:Name="translate">
                    <TranslateTransform.X>
                        <Binding ElementName="canvas" Path="ActualWidth"
                                Converter="{StaticResource multiplyConverter}" ConverterParameter="0.5" />
                    </TranslateTransform.X>
                    <TranslateTransform.Y>
                        <Binding ElementName="canvas" Path="ActualHeight"
                                Converter="{StaticResource multiplyConverter}" ConverterParameter="0.5" />
                    </TranslateTransform.Y>
                </TranslateTransform>
                <ScaleTransform ScaleX="1" ScaleY="-1" CenterX="{Binding ElementName=translate,Path=X}"
                        CenterY="{Binding ElementName=translate,Path=Y}" />
            </TransformGroup>
        </Canvas.RenderTransform>
        <Rectangle Canvas.Top="-50" Canvas.Left="-50" Height="100" Width="200" Fill="Blue" />
        <Rectangle Canvas.Top="0" Canvas.Left="0" Height="200" Width="100" Fill="Green" />
        <Rectangle Canvas.Top="-25" Canvas.Left="-25" Height="50" Width="50" Fill="HotPink" />
    </Canvas>
</Canvas>

As for your new requirements that you need varying ranges, a more complex ValueConverter would probably do the trick.

这篇关于更改WPF画布的坐标系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆