wpf - 使用 ItemsControl 时如何将 X/Y 位置转换为 Canvas Left/Top 属性

标签 wpf data-binding coordinates itemscontrol

我正在尝试使用 Canvas 来显示具有“世界”位置(而不是“屏幕”位置)的对象。 Canvas 定义如下:

<Canvas Background="AliceBlue">
    <ItemsControl Name="myItemsControl" ItemsSource="{Binding MyItems}">
        <Image x:Name="myMapImage" Panel.ZIndex="-1" />
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Canvas>
                    <TextBlock Canvas.Left="{Binding WorldX}" Canvas.Top="{Binding WorldY}"
                               Text="{Binding Text}"
                               Width="Auto" Height="Auto" Foreground="Red" />
                </Canvas>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Canvas>

MyItem 的定义如下:

public class MyItem
{
    public MyItem(double worldX, double worldY, string text)
    {
        WorldX = worldX;
        WorldY = worldY;
        Text = text;
    }
    public double WorldX { get; set; }
    public double WorldY { get; set; }
    public string Text { get; set; }
}

此外,我有一种在世界坐标和屏幕坐标之间进行转换的方法:

Point worldToScreen(double worldX, double worldY)
{
    // Note that the conversion uses an internal m_mapData object
    var size = m_mapData.WorldMax - m_mapData.WorldMin;
    var left = ((worldX - m_currentMap.WorldMin.X) / size.X) * myMapImage.ActualWidth;
    var top = ((worldY - m_currentMap.WorldMin.Y) / size.Y) * myMapImage.ActualHeight;
    return new Point(left, top);
}

在当前的实现中,项目被定位在错误的位置,因为它们的位置未转换为屏幕坐标。

在将 MyItem 对象添加到 Canvas 之前,如何对其应用 worldToScreen 方法?

<小时/>

编辑:

我有点困惑我是否走对了路,所以我发布了另一个问题:How to use WPF to visualize a simple 2D world (map and elements)

对于这个问题也有一个有用且完整的答案

最佳答案

您提供的代码的主要问题是 Canvas.LeftCanvas.Top属性是相对于 Canvas那是在 DataTemplate对于ItemsControl 。这不断“重置”原点。相反,您可以:

  • 删除 Canvas来自DataTemplate
  • 制作ItemsPanel对于ListBox一个Canvas
  • 定位ItemsPresenter包裹 ItemsControl带有 Canvas.Top 的项目和Canvas.Left
  • 确保ImageCanvas具有相同的坐标,或者切换到使用`Canvas

这是一个完整的仅 XAML 定位示例 ItemsControl Canvas 上的项目与 Image背后Canvas :

<Grid>
    <Image x:Name="image" Height="100" Width="Auto" Source="http://thecybershadow.net/misc/stackoverflow.png"/>
    <ItemsControl Name="myItemsControl">
        <ItemsControl.ItemsSource>
            <PointCollection>
                <Point X="10" Y="10"/>
                <Point X="30" Y="30"/>
            </PointCollection>
        </ItemsControl.ItemsSource>
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="Text" Foreground="Red"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
        <ItemsControl.ItemContainerStyle>
            <Style TargetType="ContentPresenter">
                <Setter Property="Canvas.Left" Value="{Binding X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Y}"/>
            </Style>
        </ItemsControl.ItemContainerStyle>
    </ItemsControl>
</Grid>

关于wpf - 使用 ItemsControl 时如何将 X/Y 位置转换为 Canvas Left/Top 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4708151/

相关文章:

objective-c - 将 NSNumber 转换为 CLCoordinate

c# - 如何在WPF中处理TabItem单击事件?

c# - 步步高棋盘游戏的绑定(bind)模式

angularjs - Angular ngModelOptions - 仅在单击按钮时将值绑定(bind)到模型

wpf - 将 ListView 自动滚动到最后添加的项目的最佳方式是什么?

wpf - 如何将顶级 MenuItem 上的 Visibility 属性绑定(bind)到 ViewModel

wpf - '成员 "Opacity"无法识别或无法访问 .' Why can' 我设置了不透明度?

wpf - 获取 wpf gridid

Android getLocationOnScreen问题: wrong coordinates

Python:通过迭代加速矩阵坐标映射