Draw lines and circles in WPF
I need to draw a graph like bus station schema: o-School----o-Church-------o-Police
.
As I have VS 2010, I thought WPF(as I understood 开发者_C百科it uses vectorized graphics) should be the good canvas to start drawing.
Is it possible, complicated, and what do you recommend for a WPF beginner.
Thanks.
EDIT: Can I set a DashStyle for the line (dash-dot, dotDot...)?
Here's something that could help you get started. It has a Canvas containing a few shapes, and a Slider control that allows you to control zooming. You can just add other elements inside the Canvas as required.
<DockPanel>
<Slider x:Name="slider" Minimum=".1" Maximum="10" Value="1" DockPanel.Dock="Top"/>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Border BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" VerticalAlignment="Center">
<Canvas Width="300" Height="300">
<Canvas.LayoutTransform>
<ScaleTransform ScaleX="{Binding ElementName=slider, Path=Value}"
ScaleY="{Binding ElementName=slider, Path=Value}"/>
</Canvas.LayoutTransform>
<Ellipse Canvas.Left="10" Canvas.Top="10" Width="20" Height="20"
Stroke="Black" StrokeThickness="1" Fill="Red"/>
<Line Canvas.Left="20" Canvas.Top="30" X1="0" X2="0" Y1="0" Y2="50"
Stroke="Black" StrokeThickness="1"/>
<Ellipse Canvas.Left="10" Canvas.Top="80" Width="20" Height="20"
Stroke="Black" StrokeThickness="1" Fill="Yellow"/>
</Canvas>
</Border>
</ScrollViewer>
</DockPanel>
EDIT:
To change the dash style for the line, simply set the StrokeDashArray property. It allows you to specify the pattern for how your line looks like. It follows a "segment length, gap length, segment length, gap length..." format, so setting this line:
<Line Canvas.Left="100" Canvas.Top="100" Stroke="Black"
X1="0" X2="100" Y1="0" Y2="0"
StrokeThickness="3" StrokeDashArray="2,2"/>
gives you this (i.e. a line made up of a series of segments with a length of 2 followed by gaps with a length of 2):
Setting the StrokeDashArray to
StrokeDashArray="5,1,1,1"
gives you the dash-dot pattern.
You have a few examples using Canvas and showing Zoom but if you only need a single line of elements you can use a StackPanel and set VerticalAlignment="Center" then you don't need to calculate the positions just the sizes of the lines.
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<StackPanel.Resources>
<Style TargetType="Ellipse">
<Setter Property="Width" Value="20" />
<Setter Property="Height" Value="20" />
<Setter Property="Stroke" Value="Orange" />
<Setter Property="StrokeThickness" Value="3" />
</Style>
<Style TargetType="Line">
<Setter Property="Stroke" Value="DodgerBlue" />
<Setter Property="StrokeDashArray" Value="5,1,1,1,1,1" />
<Setter Property="StrokeThickness" Value="2" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="Padding" Value="4" />
</Style>
<Style TargetType="Border" x:Key="Label">
<Setter Property="Background" Value="LimeGreen" />
<Setter Property="CornerRadius" Value="10" />
</Style>
</StackPanel.Resources>
<Ellipse />
<Border VerticalAlignment="Center">
<Line X2="50" />
</Border>
<Border Style="{StaticResource Label}">
<TextBlock Text="Home" />
</Border>
<Border VerticalAlignment="Center">
<Line X2="50" />
</Border>
<Ellipse />
<Border VerticalAlignment="Center">
<Line X2="50" />
</Border>
<Border Style="{StaticResource Label}">
<TextBlock Text="Church" />
</Border>
<Border VerticalAlignment="Center">
<Line X2="50" />
</Border>
<Ellipse />
<Border VerticalAlignment="Center">
<Line X2="20" />
</Border>
<Border Style="{StaticResource Label}">
<TextBlock Text="Police" />
</Border>
</StackPanel>
If you need to do multiple diagrams you can create a different DataTemplate for each type of node e.g circle, road, label and use an ItemsControl with a ItemsPanelTemplate set to do the same thing.
It is easy to draw simple shapes in WPF. You can find them in the Shapes namespace with some examples.
An example for you:
<Canvas>
<Ellipse Canvas.Top="0" Canvas.Left="0" Width="256" Height="256" />
<Line Canvas.Top="0" Canvas.Left="256" X1="0" Y1="0" X2="128" Y2=128" >
</Canvas>
This should not be complicated, I would keep it simple by putting a Canvas within a Viewbox. Increase the Canvas' Width and Height to zoom out, and Decrease them to zoom in.
<DockPanel>
<Viewbox DockPanel.Dock="Top" Width="100" Height="100" >
<Canvas Width="{Binding Path=Value, ElementName=TheZoomSlider}" Height="{Binding Path=Value, ElementName=TheZoomSlider}">
<Ellipse Stroke="Black" Canvas.Top="40" Canvas.Left="20" Width="20" Height="20" />
<Ellipse Stroke="Black" Canvas.Top="40" Canvas.Left="50" Width="20" Height="20" />
<Ellipse Stroke="Black" Canvas.Top="40" Canvas.Left="80" Width="20" Height="20" />
</Canvas>
</Viewbox>
<Slider Margin="0,400,0,0" HorizontalAlignment="Center" Orientation="Vertical" DockPanel.Dock="Bottom" Name="TheZoomSlider" Minimum="20" Maximum="800" Value="40" />
</DockPanel>
精彩评论