How do I add text to a Line UIElement? I would like to have the text placed in the middle of the line.
<Line Stroke="Black" X1="{Binding From.CanvasCenterX}" Y1="{Binding From.CanvasCenterY}" X2="{Binding To.CanvasCenterX}" Y2="{Binding To.CanvasCenterY}" StrokeThickness="2" />
Is this possible?
The following XAML code adds text to a Line UIElement. In this example the text is presented by a <TextBlock... />. The text is centered at the Line, but this can easily be changed by the TextAlignment property.
<Grid>
<TextBlock Text="{Binding RelationName}" TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Line Stroke="Black" X1="{Binding From.CanvasCenterX}" Y1="{Binding From.CanvasCenterY}" X2="{Binding To.CanvasCenterX}" Y2="{Binding To.CanvasCenterY}" StrokeThickness="2" />
</Grid>
VerticalAlignment and HorizontalAlignment places the <TextBlock../> in the <Grid../>
You need to set X2 coordinate value based on length of Text for alignment.
<Line Stroke="Black"
X1="{Binding From.CanvasCenterX}" Y1="{Binding From.CanvasCenterY}"
X2="{Binding To.CanvasCenterX}" Y2="{Binding To.CanvasCenterY}" StrokeThickness="2" />
<TextBlock Text="Line Between the Text!"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Line Stroke="Black"
X1="{Binding From.CanvasCenterX}" Y1="{Binding From.CanvasCenterY}"
X2="{Binding To.CanvasCenterX}" Y2="{Binding To.CanvasCenterY}" StrokeThickness="2" />
Related
I have a Canvas which contains static elements - those elements use binding to draw it in the right places. Now I need to draw other elements depending on items in a collection. I want to use ItemsControl, but I don't know how to do it correctly. My current pseudo-code:
<UserControl.Resources>
<RectangleGeometry x:Key="MyGeometry1">
<RectangleGeometry.Rect>
<MultiBinding Converter="{StaticResource RectConverter}">
<Binding Path="ActualWidth" ElementName="m_Canvas" />
<Binding Path="ActualHeight" ElementName="m_Canvas" />
</MultiBinding>
</RectangleGeometry.Rect>
</RectangleGeometry>
</UserControl.Resources>
<Canvas x:Name="m_Canvas">
<!-- "static" content -->
<Line x:Name="Line1" X1="{Binding Line1X1}" X2="{Binding Line1X2}" Y1="{Binding Line1Y1}" Y2="{Binding Line1Y2}"/>
<Line X1="0" X2="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Canvas}}}" Y1="0" Y2="0">
<Path Fill="#35A500"
Opacity="0.15">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<StaticResource ResourceKey="MyGeometry1" />
</GeometryGroup>
</Path.Data>
</Path>
<Line X1="{Binding Items[0].X1}" X2="{Binding Items[0].X2}" Y1="{Binding Items[0].Y1}" Y2="{Binding Items[0].Y2}"/>
<Line X1="{Binding Items[1].X1}" X2="{Binding Items[1].X2}" Y1="{Binding Items[1].Y1}" Y2="{Binding Items[1].Y2}"/>
<Line X1="{Binding Items[2].X1}" X2="{Binding Items[2].X2}" Y1="{Binding Items[2].Y1}" Y2="{Binding Items[2].Y2}"/>
</Canvas>
I tried something like this:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas>
<!-- "static" content -->
<Line x:Name="Line1" X1="{Binding Line1X1}" X2="{Binding Line1X2}" Y1="{Binding Line1Y1}" Y2="{Binding Line1Y2}"/>
<Line X1="0" X2="{Binding ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Canvas}}}" Y1="0" Y2="0">
</Canvas>
</ItemsPanelTemplate>
<!-- (...) other code -->
</ItemsControl>
But I have an error:
Error XDG0062 Cannot explicitly modify Children collection of Panel used as ItemsPanel for ItemsControl. ItemsControl generates child elements for Panel.
I understand that is because I put Line1 inside Canvas but how to make such Canvas with some kind static content and also as a container for items?
The "static content" could be put into another Canvas above or below the ItemsPresenter in the ControlTemplate of the ItemsControl:
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<Grid>
<Canvas>
<!-- "static" content -->
</Canvas>
<ItemsPresenter/>
</Grid>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
I am new to WPF. Is there a possibility that the points of the polyline in XAML
connected in such a way as is possible with the line in the example below.
The same problem is also a mini-language. Thanks
<Line Name="line" Fill="#FFDA2828" Stroke="Black"
X1="{Binding Text, ElementName=textBox1}"
Y1="{Binding Text, ElementName=textBox2}"
X2="{Binding Text, ElementName=textBox3}"
Y2="{Binding Text, ElementName=textBox4}"
Visibility ="Visible" StrokeThickness="2"
StrokeDashArray="2,2,2,2">
</Line>
this will work ,but a converter or a viewmodel is recommended to proxy the binding
anyway I've added a tester
as the text change the line is update
you will get some errors in text-> double conversions
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel>
<TextBox x:Name="TextBox1" Width="100"/>
<TextBox x:Name="TextBox2" Width="100"/>
<TextBox x:Name="TextBox3" Width="100"/>
<TextBox x:Name="TextBox4" Width="100"/>
</StackPanel>
<Canvas Grid.Column="1">
<Line Name="line" Fill="#FFDA2828" Stroke="Black"
X1="{Binding Text, ElementName=TextBox1}"
Y1="{Binding Text, ElementName=TextBox2}"
X2="{Binding Text, ElementName=TextBox3}"
Y2="{Binding Text, ElementName=TextBox4}"
Visibility ="Visible" StrokeThickness="2" StrokeDashArray="2,2,2,2">
</Line>
</Canvas>
</Grid>
<StackPanel Margin="20">
<Line StrokeDashArray="4 4" Stroke="Red" X1="0" Y1="0" X2="{Binding LeftPoint}" Y2="{Binding TopPoint}"></Line>
<TextBlock Text="Hello"></TextBlock>
<Border Height="100"></Border>
<Canvas Name="B" >
<Border Height="48"></Border>
<TextBlock Canvas.Left="{Binding LeftPoint, Mode=TwoWay}" Canvas.Top="{Binding TopPoint, Mode=TwoWay}" Text="World"></TextBlock>
</Canvas>
</StackPanel>
Above is the code sample, line is not drawn from hello to world. I would like to preserve the structure and still be able to draw the line.
Please suggest.
I guess you're missing the StrokeThickness:
<Line StrokeDashArray="4 4"
Stroke="Red" StrokeThickness="1"
X1="0" X2="{Binding LeftPoint}"
Y1="0" Y2="{Binding TopPoint}"/>
The obvious MaxWidth gets ignored and the text in the "DisplayBox" TextBlock displays the whole text even if this text continues past the parent container controls (to the edge of the silverlight area.
<win:HierarchicalDataTemplate x:Key="hierarchicalTemplate" ItemsSource="{Binding _children}">
<Border BorderThickness="0" BorderBrush="Orange" HorizontalAlignment="Stretch" Background="{Binding Converter={StaticResource BackgroundConverter}}">
<toolkit:DockPanel LastChildFill="True" Width="{Binding HeirarchyLevel, Converter={StaticResource WidthConverter}}" Height="20">
<Canvas toolkit:DockPanel.Dock="Right" Width="20" MouseLeftButtonUp="Arrow_MouseLeftButtonDown">
<Rectangle Width="20" Height="20" Fill="Transparent" />
<Line Stroke="Black" X1="5" Y1="10" X2="17" Y2="10" />
<Line Stroke="Black" X1="11" Y1="5" X2="17" Y2="10" />
<Line Stroke="Black" X1="11" Y1="15" X2="17" Y2="10" />
</Canvas>
<Ellipse Canvas.Top="5" Width="10" Height="10" Fill="Green" toolkit:DockPanel.Dock="Right" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown" />
<Canvas Width="Auto" Loaded="TextArea_Loaded">
<TextBlock Name="DisplayBox" FontFamily="Arial" FontSize="17" Foreground="Black" Width="Auto" Text="{Binding TaskName}" MouseLeftButtonUp="TextBlock_MouseLeftButtonUp" />
<TextBox Name="EditBox" FontFamily="Arial" FontSize="10" Foreground="Black" Height="20" Text="{Binding TaskName}" Visibility="Collapsed" LostFocus="TextBox_LostFocus" />
<Line Stroke="Black" X1="0" Y1="10" X2="202" Y2="10" Width="Auto" />
</Canvas>
</toolkit:DockPanel>
</Border>
</win:HierarchicalDataTemplate>
Can you switch to using a Grid instead of a canvas? A TextBlock will be appropriately clipped when it is a child of a Grid. This is not true of Canvas.
<Canvas Width="Auto" Loaded="TextArea_Loaded">
**<Border>**
<TextBlock Name="DisplayBox" FontFamily="Arial" FontSize="17" Foreground="Black" Width="Auto" Text="{Binding TaskName}" MouseLeftButtonUp="TextBlock_MouseLeftButtonUp" />
<TextBox Name="EditBox" FontFamily="Arial" FontSize="10" Foreground="Black" Height="20" Text="{Binding TaskName}" Visibility="Collapsed" LostFocus="TextBox_LostFocus" />
<Line Stroke="Black" X1="0" Y1="10" X2="202" Y2="10" Width="Auto" />
**</Border>**
</Canvas>
Should also work. (Border will honor label's maxlength. and border itself will not be visible since its thickness is 0.
Is it possible to create a Line in XAML (without any C# code behind) to align a line inside of a layout container such as a Grid?
I'd like to effectively have:
<Grid>
<Line StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Stroke="Red"/>
</Grid>
I need to use StrokeDashArray and StrokeDashOffset, otherwise I would just use a Border control with the BorderThickness set to "0,0,0,1"...
Thanks for any ideas!
To elaborate on kanchirk's response, this works for me:
<Path StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Data="M0,0 L1,0"
Stretch="Fill"
StrokeEndLineCap="Square"
StrokeStartLineCap="Square"
Stroke="Red"/>
You can also the same thing with a Line:
<Line StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
X2="1"
Stretch="Fill"
StrokeEndLineCap="Square"
StrokeStartLineCap="Square"
Stroke="Red"/>
I think you need to use Path like this
<Grid x:Name="LayoutRoot" Background="White">
<Path Fill="Red" Stretch="Fill" Stroke="Black" StrokeDashArray="1" Height="4" Margin="8,0,7,7" VerticalAlignment="Bottom" UseLayoutRounding="False" Data="M8,127 L457,127" StrokeThickness="13"/>
</Grid>
Hope this Helps. Expression Blend is a must have for this kind of Challenges or even VS 2010 RC1 (For now)
How about this?
<Line x:Name="line"
StrokeThickness="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Stroke="Red"
X2="{Binding ActualWidth, ElementName=line, Mode=OneWay}"
Stretch="Fill"
StrokeStartLineCap="Square"
StrokeEndLineCap="Square"/>