WPF UserControl as Polygon - wpf

I am very new at this WPF world, i have some experience in the classic Windows Desktop applications.
I am trying to create a custom UserControl polygon shaped.
I have tryied creating a Path Data and then setting the UserControl Opacity property to "0", but it makes transparent the whole UserControl.
For example, i have build this Polygon inside the user control
<UserControl x:Class="WindowsFormsApp2.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="640" Height="480" Opacity="100">
<Grid x:Name="LayoutRoot">
<Path Data="M-70.616296,46.859802 L7.3270039,-1.2587545 174.31959,52.958763 168.71134,98.185567 z" Fill="#FF2121D6" HorizontalAlignment="Left" Height="100" Margin="138,114,0,0" Stretch="Fill" Stroke="Black" Opacity ="100" VerticalAlignment="Top" Width="246"/>
</Grid>
As you can see the user control is 640x480 so when i add code to the UserControl_MouseLeftButtonDown event, it fires if clicking in ay position inside the 640x480 while i want only to fire when clicking inside the polygon.
I have been googling for a solution but i can't found any solution, ¿maybe what i want it's not possible?

You may template a UserControl to look like a polygon:
<UserControl x:Class="WpfApp1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Path Data="M-70.616296,46.859802 L7.3270039,-1.2587545 174.31959,52.958763 168.71134,98.185567 z"
Fill="#FF2121D6" HorizontalAlignment="Left" Height="100" Margin="138,114,0,0"
Stretch="Fill" Stroke="Black" Opacity ="100" VerticalAlignment="Top" Width="246"/>
</ControlTemplate>
</UserControl.Template>
</UserControl>
Or you may just get rid of the UserControl and use the Path element directly. It also has a MouseLeftButtonDown event that you can handle.

Related

WPF Window Not Showing Transparency Correctly

TI'm having some trouble getting my Window to be Transparent.
The Window is defined below:
<Window x:Class="HKC.Desktop.Views.UserInterfaces.RemoteKeypad"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Closing="Window_Close"
KeyDown="RemoteKeypad_KeyDown"
KeyUp="RemoteKeypad_KeyUp" MouseDown="OnMouseDown_Event"
Title="Title" Width="325" Height="370"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
I then have a border defined to give a curved edge to the Window, with a Grid inside for layout purposes:
<Border CornerRadius="20" Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border.Effect>
<DropShadowEffect BlurRadius="6" ShadowDepth="3" Color="#484948" />
</Border.Effect>
<Grid Background="Transparent" VerticalAlignment="Stretch">
....
</Grid>
</Border>
</Window>
For some reason, the first time that I open the window the background is not transparent
However, If I click away from the Window, back back on it, the transparency is working as expected.
Turns out the problem was with an external tool for adding Drop Shadows to elements.

Border control expands to size of Grid instead of just surrounding an Image control

I wanted a <Border> around my <Image> - sounds simple enough. but I could never get it to appear. I eventually made it "Red" with "BorderThickness=20" - then it was obvious that it was going around the entire "LayoutRoot"! Something like:
<UserControl x:Class="BorderCrossing.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Margin="10" Background="Black">
<Border Canvas.ZIndex="1" Background="White" HorizontalAlignment="Center" Opacity=".5" VerticalAlignment="Top">
<TextBlock x:Name="idTextBlock" FontSize="20" FontWeight="Bold" Foreground="Black" Text="ID Here" />
</Border>
<Border Canvas.ZIndex="1" Background="Blue" BorderThickness="5" BorderBrush="AntiqueWhite">
<Image x:Name="thumbnailImage" Height="100" Width="100" Stretch="Uniform" />
</Border>
</Grid>
In order to "fix" this, I found that adding 'HorizontalAlignment="Left" VerticalAlignment="Top"' to the <Border> placed the border around the <Image>, as desired. I also found that I could enclose the <Border> in a <Canvas> and achieve a similar result.
What is going on? Can someone explain this in a way that will prevent my "wonder" in the future?
Thanks,
David
The default for VerticalAlignment and HorizontalAlignment is "Stretch", so the Border stretches to the entire available space by default. It does not happen inside of a Canvas because a Canvas does not take these properties into account when performing layout of its children, so they get the minimum size based on properties like Width, Height, MinWidth and similar properties of their children. Positioning in a Canvas is done with Canvas.Top and Canvas.Left properties, while a Grid uses the ~Alignment properties as well as Margins.

Set layout to have 100% width and 100% height

How can I set a layout to have 100% width and 100% height?
I want my Silverlight application to stretch in the browser to fill all space.
I am using Expression Blend 4.
Here is my XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="RichardKnopNew.MainPage"
Width="960" Height="540">
<Grid x:Name="LayoutRoot" Width="960" Height="540">
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="/bg.jpg"/>
</Grid.Background>
<Rectangle Fill="#FF252525" Stroke="Black" Opacity="0.7" RadiusX="10" RadiusY="10" Margin="25,115,335,25" StrokeThickness="0" Height="400"/>
</Grid>
</UserControl>
Your application should do this automatically. The only reasons why it would not do so are:
You've constrained the size of the Silverlight object in the HTML page that hosts the application, or
You've explicitly set the width/height of the MainPage object in MainPage.xaml.
Setting the Background property of the MainPage object to a non-white colour should demonstrate this. If not, please include more details (including the XAML you are using).
Hope this helps...
Chris

combine image and solidcolor background for a WPF Form

I have a WPF form that I am building. I want to specify a background image for the window, which is easy enough. However, I also want to specify a color so that the area of the form not covered by the image is white. I've seen some examples that show using two different background brushes, but when I try that VS.NET tells me I can't have multiple brushes.
This is the XAML I'm using
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="Shell" WindowStyle="None" WindowState="Maximized" FontSize="24">
<Window.Background>
<ImageBrush AlignmentX="Left" AlignmentY="Top" Stretch="None" TileMode="None" ImageSource="logo_header2.png" />
</Window.Background>
<ItemsControl Background="White" VerticalAlignment="Center" cal:RegionManager.RegionName="MainRegion" >
</ItemsControl>
</Window>
This works great for the image, but the background not covered by the image is black. How do I make it white? Changing the image itself is not really an option.
Try this (I removed everything not directly relevant to the question to make the code clearer):
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="logo_header2.png" />
</Grid.Background>
<ItemsControl>
</ItemsControl>
</Grid>
</Window>
Basically, set the window's background to the behind the image color, than put a grid in the window and give the grid you background image, put everything inside the grid instead of directly in the window.
As an Extension to Nirs answer. If you want to have margins around your content, but let the background image be able to fill the whole window, you can also stack backgrounds using borders:
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="White">
<Border Padding="10">
<Border.Background>
<ImageBrush ImageSource="logo_header2.png" />
</Border.Background>
<!--<Your content >-->
</Border>
</Window>
I'm not sure you can combine brushes. You could play around with ImageBrush, or you could forget the "background" and stack the items on top of each other in a Grid:
<Window x:Class="Consent.Client.Shell"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.codeplex.com/CompositeWPF"
Title="Shell" WindowStyle="None" WindowState="Maximized" FontSize="24">
<Grid>
<Image Source="logo_header2.png" Stretch="None" VerticalAlignment="Top" />
<ItemsControl Background="White" VerticalAlignment="Center" cal:RegionManager.RegionName="MainRegion" >
</ItemsControl>
</Grid>
</Window>

How can you align a canvas background in WPF?

I have set a canvas' background to an image of a company logo. I would like for this image to be aligned to the bottom right corner of the canvas.
Is it possible to do this, or would it require for the image to be added into the canvas as a child? That would not work with this program as all children of the canvas are handled differently.
Thank You
Will this work? (It worked for me, anyway.)
<Canvas>
<Canvas.Background>
<ImageBrush ImageSource="someimage.jpg" AlignmentX="Right"
AlignmentY="Bottom" Stretch="None" />
</Canvas.Background>
</Canvas>
AFAIK The WPF Canvas needs child UI elements to be positioned using absolute co-ordinates.
To achieve the right-bottom-anchored effect, I think you'd need to handle the window resize event, recalculate and apply the Top,Left co-ordinates for the child Image element to always stick to the right buttom corner.
<Window x:Class="HelloWPF.Window1" xmlns...
Title="Window1" Height="300" Width="339">
<Canvas>
<Image Canvas.Left="195" Canvas.Top="175" Height="87" Name="image1" Stretch="Fill" Width="122" Source="dilbert2666700071126ni1.gif"/>
</Canvas>
</Window>
How about containing the canvas and image inside of a Grid control like so?
<Window ...>
<Grid>
<Canvas/>
<Image HorizontalAlignment="Right" VerticalAlignment="Bottom" .../>
<Grid>
</Window>
This is my solution using a border inside the canvas to align the image. This solution works well when canvas is resized:
<Canvas x:Name="MiCanvas" Height="250" Width="500" Background="Aqua">
<Border x:Name="MiBorderImage"
Width="{Binding ElementName=MiCanvas, Path=ActualWidth}"
Height="{Binding ElementName=MiCanvas, Path=ActualHeight}"
Background="Transparent">
<Image x:Name="MiImage" Source="/GraphicsLibrary/Logos/MiLogo.png"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Stretch="None" />
</Border>
</Canvas>

Resources