I'm fairly new to WPF and looking for a simple solution to the problem described below. I've tried to make this as short as possible.
I'm trying to visualize a "world" that is modeled by:
- A map image, with a known origin in meters (e.g. top-left corner is 14,27) and resolution in cm/pixel. The map keeps growing every few seconds. Maps are small so no paging/tiling is required.
- Real-world elements and points of interest. Each element has a 2D position in meters within the map area. Also, each element might move.
Regarding the model side, I have a WorldState class that keeps the map and elements:
interface IWorldState
{
IEnumerable<IWorldElement> Elements { get; }
IMapData CurrentMap { get; }
}
interface IWorldElement
{
WorldLocation { get; }
event EventHandler LocationChanged;
}
interface IMapData
{
string FilePath { get; }
WorldLocation TopLeft { get; }
Size MapSize { get; }
}
Now regarding the visualization, I've chosen the Canvas class to draw the map and elements. Each type of element (inherits from IWorldElement) should be drawn differently. There might be more than one map canvas, with a subset of the elements.
<Canvas x:Name="mapCanvas">
<Image x:Name="mapImage" />
</Canvas>
In code, I need to set the map image file when it changes:
void MapChanged(IWorldState worldState)
{
mapImage.Source = worldState.CurrentMap.FilePath;
}
To draw the elements, I have a method to convert WorldLocation to (Canvas.Left, Canvas.Top) :
Point WorldToScreen(WorldLocation worldLocation, IWorldState worldState)
{
var topLeft = worldState.CurrentMap.TopLeft;
var size = worldState.CurrentMap.Size;
var left = ((worldLocation.X - topLeft.X) / size.X) * mapImage.ActualWidth;
var top = ((worldLocation.Y - topLeft.Y) / size.Y) * mapImage.ActualHeight;
return new Point(left, top);
}
Now for the question, how should I glue the world model and the canvas together? This can be summarized by:
- Where to put the MapChanged and WorldToScreen functions.
- When an element moves the world location needs to be converted to screen coordinates.
- Each type of element should be drawn differently, for example ellipse with text or filled rectangle.
What is the recommended way to implement the "glue" layer when using WPF?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…