wpf Why is this path being scaled weirdly? - wpf

Can someone tell me why the purple path is not to the same scale as the second path? They are set in the control template for togglebutton, shown below. In addition, you can see the result here:
http://picpaste.com/weird_path-nxRoeKjb.jpg
<Grid x:Name="ToggleButtonGrid"
Background="Navy"
>
<Path x:Name="ExpandPath"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Fill"
Fill="Gray"
Stroke="Purple"
Data="M 0 0 L 12 0 L 12 12 L 0 12 Z" />
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Gray"
Stretch="Fill"
Stroke="Yellow"
Data="M 0 6 L 12 6 Z" />
</Grid>
which is then set in the controltemplate for the treeview. I don't see why it is being resized. Both of them are just contained in a grid. I would expect the grid to resize, but I am getting this
<ControlTemplate TargetType="{x:Type TreeViewItem}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="TreeViewExpanderColumn" MinWidth="19"
Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<ToggleButton x:Name="Expander"
Style="{StaticResource ExpandCollapseToggleStyle}"
IsChecked="{Binding Path=IsExpanded,
RelativeSource={RelativeSource TemplatedParent}}"
ClickMode="Press"/>
<Border Name="Bd"
Grid.Column="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="0"
Padding="0">
<ContentPresenter x:Name="PART_Header"
ContentSource="Header"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/>
</Border>
<ItemsPresenter
x:Name="ItemsHost"
Margin="-19,0,0,0"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"/>

It was an issue with using a Path to draw a line and some scaling. Not sure what was going on, but using a Line instead fixed it.
<Path
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Fill"
Fill="Gray"
Stroke="White"
Data="M 0 0 L 12 0 L 12 12 L 0 12 Z" />
<Line
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Gray"
X1="0"
Y1="0"
X2="12"
Y2="0"
Stroke="White"
/>
<Line x:Name="VerticalCrossBar"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Gray"
X1="0"
Y1="0"
X2="0"
Y2="12"
Stroke="White"
/>

Related

I want to implement it as shown in the picture.(Draw Diagonal Line in WPF)

I want to implement it like the picture above.
<Grid>
<Border BorderThickness="1" BorderBrush="#eeeeee" Height="200" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Background="#55a0c4">
<TextBlock Text="묘도대교 PY1 탑정부" Padding="6" Foreground="White"/>
</Border>
<Border Grid.Column="1" Background="White" Margin="0 0 0 0">
<Path Stroke="#55a0c4" StrokeThickness="1" Stretch="Fill" Margin="0 4 0 0">
<Path.Data>
<LineGeometry StartPoint="1,0" EndPoint="0,1" />
</Path.Data>
</Path>
</Border>
<Border Background="#55a0c4" Grid.Column="2" VerticalAlignment="Top" Height="5"/>
</Grid>
</Border>
</Grid>
The above picture and code are embodied by me, but I cannot fill the background only in the above margin. What should I do?
You just need a different geometry. Instead of drawing a line, draw a triangle. This will fill most of the area you want. Then you just need to also include a rectangle to fill the space above the triangle. Here's a version of your code that does what you want:
<Border BorderThickness="1" BorderBrush="#eeeeee" Height="200" Width="300">
<Grid SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Background="#55a0c4">
<TextBlock Text="묘도대교 PY1 탑정부" Padding="6" Foreground="White"/>
</Border>
<Border Grid.Column="1" Background="White" Margin="0 0 0 0">
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Path Fill="#55a0c4" Stretch="Fill" Margin="0 5 0 0" Data="M 0,0 H 1 L 0,1 Z"/>
<Rectangle Fill="#55a0c4" Height="5" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
</Grid>
</Border>
<Border Background="#55a0c4" Grid.Column="2" VerticalAlignment="Top" Height="5"/>
</Grid>
</Border>
Looks like this:
Please note that I also added SnapsToDevicePixels="True" to the parent Grid element. This is necessary to inhibit antialiasing that would result in faint gaps between the graphical elements.
I also used the "Path Markup Syntax" to define the triangle, instead of building the Path object's data with explicit XAML elements. I find this much more concise, if sometimes not as readable.

How can I draw this shape in xaml WPF?

I have to draw this shape in XAML. How can I draw this?
I tried this and this is OK but can't split two color
<Path Grid.Column="1" Fill="Red">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry Center="5,0" RadiusX="5" RadiusY="5" />
<RectangleGeometry Rect="0,0 5 80" />
<RectangleGeometry Rect="5,0 5 80" />
<EllipseGeometry Center="5,80" RadiusX="5" RadiusY="5" />
</GeometryGroup>
</Path.Data>
</Path>
You may use two Paths in a Canvas like these:
<Canvas>
<Path Fill="Yellow" Data="M0,0 A5,5 0 0 0 5,5 L5,75 A5,5 0 0 0 0,80Z"/>
<Path Fill="Red" Data="M5,5 A 5,5 0 0 0 10,0 L10,80 A5,5 0 0 0 5,75Z"/>
</Canvas>
For details, see Path Markup Syntax.
There are several ways. Perhaps the easiest one would be to create a Grid with two Ellipse elements that overlay the yellow and red parts:
<Grid Width="50" Height="200">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Background="Yellow" />
<Grid Background="Red" Grid.Column="1" />
<Ellipse Width="50" Height="50" Fill="White" Grid.ColumnSpan="2" VerticalAlignment="Top" Margin="0,-25,0,0" />
<Ellipse Width="50" Height="50" Fill="White" Grid.ColumnSpan="2" VerticalAlignment="Bottom" Margin="0,0,0,-25" />
</Grid>

Menu subitem will not stay open on click wpf

I need the Menu sub menu to stay open on click, i am using data template for my menuitems, and itemssource is a list of custom object,i am also using control template for menuitem, the problem is when an item is clicked on , the menu closes,here is the code for menuitem:
<MenuItem HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="64" Height="{Binding ElementName=menu,Path=ActualHeight}"
HeaderTemplate="{DynamicResource wifiIcon}" HorizontalAlignment="Stretch" Name="wifiMenuItem"
StaysOpenOnClick="True" ItemTemplate="{StaticResource WifiNetworkDataTemplate}">
<Border BorderThickness="1" BorderBrush="Black"></Border>
</MenuItem>
the datatemplate code:
<DataTemplate x:Key="WifiNetworkDataTemplate" DataType="{x:Type model:WifiNetwork}">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" Margin="0,10,0,0" Background="Transparent" x:Name="wifiStack">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Viewbox Grid.Column="0" x:Name="check" Width="16" Height="16" Visibility="{Binding IsConnected, Converter={StaticResource BooleanToVisibilityConverter}}" >
<Canvas Width="24" Height="24">
<Path Data="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z" Fill="Blue" />
</Canvas>
</Viewbox>
<Viewbox Grid.Column="3" x:Name="wifiSignal" Width="16" Height="16" Margin="10,0,0,0" >
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x:Name="icon_vm_wifi" Width="32" Height="32">
<Path Fill="White" Data="M16.030 10.038c-4.179 0-8.082 1.662-10.992 4.678-0.207 0.216-0.201 0.557 0.015 0.764 0.104 0.101 0.239 0.152 0.374 0.152 0.141 0 0.283-0.055 0.389-0.165 2.706-2.802 6.333-4.348 10.214-4.348 3.809 0 7.388 1.495 10.077 4.208 0.208 0.21 0.553 0.214 0.765 0.004 0.211-0.211 0.213-0.555 0.004-0.765-2.894-2.922-6.745-4.529-10.846-4.529z" />
<Path Fill="White" Data="M29.821 11.573c-3.796-3.409-8.695-5.287-13.791-5.287-5.127 0-10.047 1.897-13.852 5.343-0.222 0.201-0.239 0.543-0.038 0.765 0.108 0.117 0.253 0.178 0.401 0.178 0.129 0 0.26-0.046 0.363-0.139 3.604-3.265 8.266-5.064 13.125-5.064 4.829 0 9.471 1.779 13.068 5.010 0.222 0.202 0.564 0.184 0.763-0.041 0.201-0.222 0.182-0.563-0.040-0.764z" />
<Path Fill="White" Data="M16.030 13.425c-3.19 0-6.183 1.59-8.009 4.253-0.169 0.246-0.108 0.582 0.139 0.751 0.093 0.066 0.201 0.095 0.306 0.095 0.171 0 0.34-0.082 0.446-0.235 1.625-2.367 4.284-3.783 7.117-3.783 2.82 0 5.476 1.405 7.1 3.758 0.171 0.246 0.507 0.307 0.752 0.137 0.247-0.17 0.308-0.507 0.137-0.753-1.827-2.645-4.812-4.224-7.99-4.224z" />
<Path Fill="White" Data="M16.030 17.987c-2.129 0-3.862 1.734-3.862 3.863 0 2.129 1.732 3.864 3.862 3.864s3.864-1.734 3.864-3.864c0-2.128-1.734-3.863-3.864-3.863zM16.030 24.632c-1.534 0-2.78-1.248-2.78-2.782s1.246-2.781 2.78-2.781 2.782 1.247 2.782 2.781c0 1.534-1.248 2.782-2.782 2.782z" />
</Canvas>
</Viewbox>
<Viewbox Grid.Column="2" x:Name="passwordNeeded" Width="16" Height="16" Margin="10,0,0,0" Visibility="{Binding IsSecure, Converter={StaticResource BooleanToVisibilityConverter}}" >
<Canvas Width="24" Height="24">
<Path Data="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z" Fill="Black" />
</Canvas>
</Viewbox>
<TextBlock Grid.Column="1" TextAlignment="Left" x:Name="wifiName" Text="{Binding Name}" HorizontalAlignment="Left" ></TextBlock>
</Grid>
<TextBlock x:Name="invalidPasswordTextBlock" Visibility="Collapsed"/>
<PasswordBox x:Name="wifiPasswordBox" Visibility="{Binding PasswordBoxShown, Converter={StaticResource BooleanToVisibilityConverter}}" />
</StackPanel>
</DataTemplate>
code for menuitem's control template:
<!--Menu Item-->
<ControlTemplate x:Key="menuItem1" TargetType="{x:Type MenuItem}">
<Border x:Name="templateRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<Grid>
<Border x:Name="GlyphPanel" Background="Transparent"/>
<ContentPresenter Content="{TemplateBinding Header}" Height="{TemplateBinding Height}" Width="{TemplateBinding Width}"
ContentTemplate="{TemplateBinding HeaderTemplate}" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
/>
<Popup x:Name="Popup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="True"
StaysOpen="{TemplateBinding StaysOpenOnClick}"
PopupAnimation="Fade">
<Border Padding="10" Background="White" Opacity="0.7">
<ItemsPresenter HorizontalAlignment="Center" />
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter TargetName="templateRoot" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="{x:Type MenuItem}" TargetType="{x:Type MenuItem}">
<Setter Property="Template" Value="{StaticResource menuItem1}"/>
</Style>
solved it by using a another menuitem inside wifimenuitem and setting its StaysOpenOnClick="True" and used a listbox and set its itemtemplate and itemssource in code:
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<ListBox x:Name="myListbox" ItemTemplate="{StaticResource WifiNetworkDataTemplate}" Focusable="True"></ListBox>
</MenuItem.Header>
</MenuItem>

Center a circle in a square

Say I have the following controls (that I want to put in a Data Template):
<Rectangle Width="20" Height="20" Stroke="Black"/>
<Ellipse Width="15" Height="15" Stroke="Red" StrokeThickness="4"/>
I would like the circle to be centered exactly in the middle of the square.
Seems easy, but I am just not figuring how to do it. Everything I try is off to one side or the other by a bit.
Update:
This is my latest attempt that did not work:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="3"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="3"/>
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="3" Width="20" Height="20" Stroke="Black"/>
<Ellipse Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="15" Height="15" Stroke="Red" StrokeThickness="3"/>
</Grid>
It is the closest I can get.
If you have an even-length and an odd-length shape, they can never be perfectly aligned. Like a 2-unit line and a 3-unit line, they'll always be slightly off:
---
--
So could I suggest making them both even-length, or both odd-length?
<Grid>
<Rectangle Width="20" Height="20" Stroke="Black"/>
<Ellipse Width="16" Height="16" Stroke="Red" StrokeThickness="4"/>
</Grid>

Path with broken shadow effect

I hope that it is clear enough in the image, I have a triangle with shadow effect that doesn't look so good, seems to be broken somehow.
Any help will be greatly appreciated.
(Update: the rectangle and the path have to be separated)
XAML:
<Grid Height="50" Width="60" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="1" Stroke="Black" Fill="White">
<Rectangle.Effect>
<DropShadowEffect Opacity="0.5" ShadowDepth="4" BlurRadius="10" />
</Rectangle.Effect>
</Rectangle>
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Margin="0,15,-1,15"
Data="M44.386378,164.8791 L22.983157,171.42119 44.713478,176.58567" Width="23.167">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>
</Grid>
</Grid>
On your triangle:
Remove the Margin
Set the Path height explicitly ("22" is pretty close what you have there).
That should prevent the triangle's shadow from being clipped.
Here's the xaml for that:
<Grid Height="50" Width="60" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="1" Stroke="Black" Fill="White" >
<Rectangle.Effect>
<DropShadowEffect Opacity="0.5" ShadowDepth="4" BlurRadius="10" />
</Rectangle.Effect>
</Rectangle>
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left"
Data="M44.386378,164.8791 L22.983157,171.42119 44.713478,176.58567" Width="23.167" Height="22">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>
</Grid>
The problem is you have two separate elements each with a drop shadow. You cannot expect their shadows to join up nicely, the 'blur' is applied separately to each element. Try combining your rectangle and triangle into a single path. e.g.
<Path Fill="White" Stretch="Fill" Stroke="Black" HorizontalAlignment="Left" Margin="0,15,-1,15"
Data="M 0,0 L 100,0 L 100,400 L 0,400 L 0,300 L -50, 200 L 0, 100 L 0,0">
<Path.Effect>
<DropShadowEffect BlurRadius="10" Opacity="0.5" ShadowDepth="4" />
</Path.Effect>
</Path>

Resources