How to "punch a hole" in a WPF window [duplicate] - c#

This question already has answers here:
Create a transparent hole inside a window's background - WPF
(2 answers)
Closed 3 years ago.
Im starting with WPF now, and I dont know if its possible, but it should be.
Im trying to create a fully transparent area in my form, deleting all the contents inside a rectangle (Those contents will be a AxWindowsMediaPlayer, as Shown below), and be able to see whats behind my window.
Its possible in WinForms using TransparencyKey and a Panel, but WinForms doesnt fill my needs for this project.
Example:
Another example:

this should do the trick for you:
<Window
[...]
Title="MainWindow" MinHeight="200" MinWidth="400" WindowStyle="None" AllowsTransparency="True">
<Window.OpacityMask>
<ImageBrush
ViewportUnits="RelativeToBoundingBox"
TileMode="None"
ImageSource="/Images/rect.png"
/>
</Window.OpacityMask>
<!-- many many controls-->
</Window>
WindowStyle need to be none
AllowTransparency needs to be true
And the image source is just a image with a rectagular transparent part in center. You could also draw this dinamically!
result:

<Window x:Class="WpfApp5.MainWindow"
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"
xmlns:local="clr-namespace:WpfApp5"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
WindowStyle="None"
Opacity="0.1"
AllowsTransparency="True">
</Window>
Make WindowStyle="None" and AllowsTransparency="True" to get transparent window. vary opacity to get amount of transparency

Got something like this.
<Window x:Class="WpfApp3.MainWindow"
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"
Title="MainWindow" Height="450" Width="800" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Fill="#66FFFFFF" Grid.Column="0" Grid.RowSpan="3"/>
<Rectangle Fill="#66FFFFFF" Grid.Column="2" Grid.RowSpan="3"/>
<Rectangle Fill="#66FFFFFF" Grid.Column="1" Grid.Row="0"/>
<Rectangle Fill="#66FFFFFF" Grid.Column="1" Grid.Row="2"/>
<Rectangle x:Name="workingRectangle" Fill="Transparent" Stroke="Red" Grid.Column="1" Grid.Row="1"/>
</Grid>
</Window>

Masking is probably the closest substitute to Windows Forms' TransparencyKey.

Related

Can a WPF control be centered around its parent but also respect the position of its sibling control using xaml only?

I'm trying to center a modal popup-style control on a xaml screen relative to the entire screen, but also have the central control get pushed out of the way by a sibling (side panel) in the event the control is so large the two would intersect. This is feasible with codebehind, datanbindings, data triggers, custom controls and other less than totally elegant approaches, but is there a way to solve this problem out of the box with only xaml?
Here's a greatly simplified version of the problem which is a window with two rectangles. The orange rectangle is always 200px. The green rectangle is variably sized but never larger than 600px. Can we make the green rectangle center on the screen unless it is wide enough that it would collide with the orange rectangle in which case the green rectangle is laid out to the right of the orange rectangle (like a stackpanel)? The green and orange rectangles can be placed into any containers you want and the containers can be nested any way you want.
<Window x:Class="WpfApp1.MainWindow"
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"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid Width="800">
<Rectangle Width="200" Fill="Orange" HorizontalAlignment="Left" ></Rectangle>
<Rectangle Width="300" Fill="Green" HorizontalAlignment="Center"></Rectangle>
</Grid>
</Window>
There is no built-in way to do this, but this approach works and is fairly simple:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Width="200" Fill="Orange" HorizontalAlignment="Left" />
<Rectangle Grid.Column="1" Width="300" Fill="Green" HorizontalAlignment="Center"/>
</Grid>
And if you prefer not to duplicate the width of the orange rectangle you can do this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="{Binding ElementName=OrangeRectangle, Path=ActualWidth}"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle x:Name="OrangeRectangle" Width="200" Fill="Orange" HorizontalAlignment="Left" />
<Rectangle Grid.Column="1" Width="300" Fill="Green" HorizontalAlignment="Center"/>
</Grid>

XAML ProgressBar is blue and thin in WPF

I want to create an Indeterminate progress bar that keeps on loading until a certain task finishes. However, it currently does not look like the default progress bar that I knew, colored green and thick, even though I haven't made any changes in this regard. This is how it looks:
actual dialog
<Window x:Class="Contributor.AnalyticsSyncDialog"
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"
WindowStyle="None" WindowStartupLocation="CenterScreen" Height="70" Width="250" Background="#EEEEEE" Loaded="AnalyticsSync_OnLoaded" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Saving Components..." Height="18" Margin="5" Background="Transparent"/>
<ProgressBar x:Name="Bar" IsIndeterminate="True" Background="Transparent" Grid.Row="1" Height = "5" Margin="5,10"/>
</Grid>
</Window>
Moreover, the preview within the designer looks as I'd expect it to be.
expected dialog
What could be the cause of this discrepancy?

Wrappanel children not streching while resize the window

I am a beginner in using WPF and try to create a responsive application. I read many blogs and websites about the responsive design possibilities in WPF. Now I try to create a sample form. Please see the below image to find element structure in my form.
In this image first red box layout was maximized window and the second one was the resized or small screen layout
Red box is main container grid and it have to column (column definition)
Blue Boxes are two children of the main grid ( first blue box is a grid and second is wrappanel )
Green boxes in side the second blue box are the child elements of the wrap panel.
I am try to when I resize the window I need to change wrap panel contents like above image. I mean wrappanel orientation is horizontal, child contents are arranged in newline if the space not available on the right side.
please see the sample code below.
<Window x:Class="ResponsiveWPFApp.Responsive"
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"
xmlns:local="clr-namespace:ResponsiveWPFApp"
mc:Ignorable="d"
Title="Responsive" Height="450" Width="800">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200*"/>
<ColumnDefinition Width="400*"/>
</Grid.ColumnDefinitions>
<Grid Background="Yellow">
</Grid>
<WrapPanel x:Name="wrPanel" Background="Aqua" Grid.Column="1" Orientation="Horizontal" ItemWidth="Auto">
<WrapPanel.Children>
<Grid x:Name="gd1" Height="400" Width="Auto" HorizontalAlignment="Stretch" Background="Black" >
<TextBlock>terdf</TextBlock>
</Grid>
<Grid x:Name="gd2" Height="400" Width="Auto" Background="Green" >
<TextBlock >sdfdf</TextBlock>
</Grid>
</WrapPanel.Children>
</WrapPanel>
</Grid>
</Grid>
</Window>
In my code wrap panel contains two child elements, it's not filled the wrap panel available space.
You must decide: either you need to stretch the children, or you need WrapPanel. These are mutually exclusive options. The main purpose of the WrapPanel is to transfer the children to the next line (column) if they do not fit in the current line. If each child is stretched horizontally (vertically) to the limit, then each line will always have one child, and the functionality of the WrapPanel will lose its meaning. If you need to stretch children, you should use a Grid or UniformGrid. Here is an example of code with Grid in which children are stretched:
<Window x:Class="ResponsiveWPFApp.Responsive"
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"
xmlns:local="clr-namespace:ResponsiveWPFApp"
mc:Ignorable="d"
Title="Responsive" Height="450" Width="800">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200*"/>
<ColumnDefinition Width="400*"/>
</Grid.ColumnDefinitions>
<Grid Background="Yellow">
</Grid>
<Grid x:Name="grid" Background="Aqua" Grid.Column="1" VerticalAlignment="Top" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" x:Name="gd1" Height="400" HorizontalAlignment="Stretch" Background="Black" >
<TextBlock>terdf</TextBlock>
</Grid>
<Grid Grid.Column="1" x:Name="gd2" Height="400" Background="Green" >
<TextBlock >sdfdf</TextBlock>
</Grid>
</Grid>
</Grid>
</Grid>
</Window>
UniformGrid is a hybrid WrapPanel and Grid. Here is code snipet with UniformGrid:
<Window x:Class="ResponsiveWPFApp.Responsive"
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"
xmlns:local="clr-namespace:ResponsiveWPFApp"
mc:Ignorable="d"
Title="Responsive" Height="450" Width="800">
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200*"/>
<ColumnDefinition Width="400*"/>
</Grid.ColumnDefinitions>
<Grid Background="Yellow">
</Grid>
<UniformGrid x:Name="grid" Background="Aqua" Grid.Column="1" Rows="1" VerticalAlignment="Top" >
<Grid x:Name="gd1" Height="400" HorizontalAlignment="Stretch" Background="Black" >
<TextBlock>terdf</TextBlock>
</Grid>
<Grid x:Name="gd2" Height="400" Background="Green" >
<TextBlock >sdfdf</TextBlock>
</Grid>
</UniformGrid>
</Grid>
</Grid>
</Window>
Take account on Rows="1" for the UniformGrid. Number of Rows is fixed for the UniformGrid. WrapPanel may have different number of rows.

Avoid blank window shown before MediaElement

I have created a WPF C# application.
I have put a MediaElement into it which plays a video. When i run the application, a blank window which is the parent window of MediaElement is shown for a second or 2 and then video starts playing.
I don't want to show this blank window. I just wanna show the video directly.
Do anyone know how to fix this, please help.
Thanks in advance.
<Window x:Class="MyWindow.MainWindow"
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"
xmlns:local="clr-namespace:MyWindow"
mc:Ignorable="d"
Title="" Height="2160" Width="3840"
WindowState="Maximized"
WindowStartupLocation="CenterScreen"
Loaded="Window_Loaded"
WindowStyle="None"
AllowsTransparency="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="320*"/>
<RowDefinition Height="50*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="MediaPlayer" Grid.RowSpan="2" LoadedBehavior="Manual" Loaded="MediaPlayer_Loaded" MediaEnded="MediaPlayer_MediaEnded" Source="Video.mp4" Margin="0,0,0,0"/>
<Label Name="My_Content" Content="My Content" Width="500" Height="100" HorizontalAlignment="Center" VerticalAlignment="Bottom" Canvas.Top="1598" Foreground="White" FontSize="48" FontFamily="font_family" FontWeight="Regular" Margin="1666,0,1666,30"/>
<Label Name="My_Label" Content="My Label" Width="1000" Height="100" Canvas.Top="10" Foreground="White" FontSize="48" FontFamily="font_family" FontWeight="Regular" Margin="1376,46,1456,145" Grid.Row="1"/>
<Image Name="My_Image" Source="Photo.png" InkCanvas.Top="530" InkCanvas.Left="2330" Width="1400" Height="660"/>
</Grid>
</Window>

How to get WPF Window to autosize to content and no more

I have a dialog containing 2 TextBlocks, a Progress Bar and a cancel Button.
Here is the XAML:
<Window x:Class="WpfApplication4.MainWindow"
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"
xmlns:local="clr-namespace:WpfApplication4"
mc:Ignorable="d"
Title="MainWindow" Height="Auto" Width="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock x:Name="txtFirst" Grid.Row="0" Margin="5" TextWrapping="Wrap">This is a really really really really long string that wraps</TextBlock>
<TextBlock x:Name="txtSecond" Grid.Row="1" Margin="5" Text="A Shorter string" TextWrapping="Wrap" MaxWidth="200"/>
<ProgressBar x:Name="prgProgress" Grid.Row="2" Margin="5" Height="20" />
<Button x:Name="btnCancel" Grid.Row="3" Margin="5" Height="25" Width="50"/>
</Grid>
</Window>
I would like the Window not to have a fixed height but auto adjust its height based on the size of its children and no more, but can’t see a way to do this. At the moment when I don’t assign anything to the Window’s height, it seems to adopt a height that is much bigger that the content.
Not sure why, or where it gets height value from? If I set Windows Height = “Auto” I get the same thing. All the heights for the RowDefinitions are set to “Auto”, which I take to mean ‘set row height to be row child height’.
You need to use SizeToContent property, check the msdn link.
Example:
<Window 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"
…
SizeToContent="WidthAndHeight">

Categories