I want to create a new UserControl and reroute the Background property to use it elsewhere than in the UserControl.Background property (like it is done on the checkbox for example).
Here is a simple custom usercontrol:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Controls"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
x:Class="Controls.HexagonalTile"
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="300">
<Grid>
<ed:RegularPolygon Fill="{Binding ElementName=LayoutRoot, Path=Background}" StrokeThickness="5" Stroke="Black"/>
</Grid>
And I want to use it like this:
<Controls:HexagonalTile HorizontalAlignment="Left" Height="100" Width="100" Background="Aqua" />
But when I do this, the corner of my user control, outside of the hexagone, take the background color too. I want them to stay transparent.
Thank's for your help.
The reason why this is happening is because the default ControlTemplate for a UserControl has a Border with a TemplateBinding to the Background property.
However, you can re-template the control like this to achieve your goal:
<UserControl x:Class="WpfApp4.HexagonalTile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing">
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
<Grid>
<ContentPresenter />
</Grid>
</ControlTemplate>
</UserControl.Template>
<Grid>
<ed:RegularPolygon
Fill="{Binding Background, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Stroke="Black"
StrokeThickness="5" />
</Grid>
</UserControl>
I hope this helps!
Related
I've done some searching but I can't seem to find a way to use both a drop shadow on my window, and have the window's background blurred.
I'm currently using https://github.com/riverar/sample-win32-acrylicblur (all blur code in MainWindow.xaml.cs) to blur the background, but since the dropshadow requires some padding in the window to render the dropshadow in, the space of the dropshadow gets the blur applied to it too.
I tried using an OpacityMask, but that didn't seem to help. In fact, even when setting the Window's Opacity property to 0, the blur still showed, so I fear that it's not possible with this method of blurring.
One of the packages I already am using is Microsoft.Windows.Shell, which I need to rebuild the default buttons I lose after applying the drop shadow, perhaps this has something helpful.
TLDR:
Is there a way to use an Aero-style blurred Window and a drop shadow together? Ideally without installing extra packages, but if there's no other way I'll have to bite the bullet.
I'm on the latest versions of .Net etc. as of 03/08/2018
Do you mean the effect shown below?
If so, you can write the XAML code to get it.
<Window x:Class="Walterlv.Demo.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"
AllowsTransparency="True" WindowStyle="None" Background="{x:Null}">
<Grid>
<Rectangle x:Name="ShadowShape" Fill="White" Margin="8">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Rectangle.Effect>
</Rectangle>
<Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
<Rectangle x:Name="BlurringShape" Margin="-32">
<Rectangle.Fill>
<ImageBrush ImageSource="Sample.jpg"/>
</Rectangle.Fill>
<Rectangle.Effect>
<BlurEffect KernelType="Gaussian" Radius="32" />
</Rectangle.Effect>
</Rectangle>
<Border.CacheMode>
<BitmapCache />
</Border.CacheMode>
</Border>
</Grid>
<Grid>
<!-- Write your own content here... -->
</Grid>
</Window>
Notes:
I write three UIElement to implement that effect:
The BlurringShape renders a bitmap and blur itself. It blurs at the radius 32, so it should set a -32 margin to avoid the transparent blur.
The BackgroundBorder clips the BlurringShape so that the blur will not spill over.
Because we have clipped the BackgroundBorder, so if we set a DropShadowEffect on it, it will be clipped. We should create another shape to render the DropShadowEffect. That is the ShadowShape.
If you want your style more reusable, you can take this code below:
<Window x:Class="Walterlv.Demo.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">
<Window.Background>
<ImageBrush ImageSource="High+Sierra.jpg"/>
</Window.Background>
<Window.Style>
<Style TargetType="Window">
<Setter Property="AllowsTransparency" Value="True" />
<Setter Property="WindowStyle" Value="None" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid>
<Rectangle Fill="White" Margin="8">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="8" ShadowDepth="0" />
</Rectangle.Effect>
</Rectangle>
<Border x:Name="BackgroundBorder" Margin="8" ClipToBounds="True">
<Rectangle Margin="-32" Fill="{TemplateBinding Background}">
<Rectangle.Effect>
<BlurEffect KernelType="Gaussian" Radius="32" />
</Rectangle.Effect>
</Rectangle>
<Border.CacheMode>
<BitmapCache />
</Border.CacheMode>
</Border>
<ContentPresenter Margin="8" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
<Grid>
<!-- Write your own content here ... -->
</Grid>
</Window>
I have a custom designed window as shown below.
Custom Window
The following is my XAML design with the styles omitted for simplicity.
<Window x:Class="CustomWindowBase.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:CustomWindowBase"
mc:Ignorable="d"
Title="CustomWindow" Height="600" Width="870" WindowStartupLocation="CenterScreen"
ResizeMode="NoResize" AllowsTransparency="True" WindowStyle="None" Background="Transparent">
<Border Style="{StaticResource MainWindowBorderStyle}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="35"/>
<RowDefinition Height="590*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Style="{StaticResource TitleBarBorderStyle}">
<Grid>
<TextBlock Style="{StaticResource TitleStyle}" Text="Custom Window"/>
<Button x:Name="BtnClose" Style="{StaticResource CloseButtonStyle}"/>
</Grid>
</Border>
<Grid Grid.Row="1">
<!-- Different User Control Here -->
</Grid>
</Grid>
</Border>
</Window>
There's two events for the code behind of this window that supports the close/drag action.
How can I reuse this shell for every other window that my application will potentially open, sort of like a base class that can be inherited?
If at all possible, I wouldn't want to do much in the code behind, like instantiating an instance of this window shell and assigning it's content with another user control.
Your help is much appreciated.
Put the XAML stuff in a ControlTemplate.
For the <!-- Different User Control Here --> part, insert a <ContentPresenter />. It knows what to do. It just knows.
Apply the template, and the other desired property values, with a Style.
If I got you right, then it's fine. Call it from outside the window with
new MainWindow().ShowDialog();
Is it possible to set my StackPanel or Grid to be position absolute like CSS.
In CSS is have property Position of the elements and can set to be relative, absolute and is working good.
In XAML can make Grid, StackPanel to use position absolute.
You have to use Canvas in order to set absolute position in WPF.
In case of buttons in a window, here is a sample :
<Window x:Class="tobedeleted.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="350" Width="525">
<Canvas>
<Button Canvas.Left="10" Canvas.Bottom="20">Bottom left</Button>
</Canvas>
</Window>
The output is :
Feel free to ask if help is needed.
Absolute positioning defeats the purpose of WPF, but I agree, sometimes there is no other way so you have two basic options.
Elements under the root grid
Elements in a canvas that is the same size as the window (as Vasilievski pointed out)
Code example:
<Window x:Class="WpfApplication1.Window3"
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:WpfApplication1"
mc:Ignorable="d"
Title="Window3" Height="300" Width="300">
<Grid>
<Rectangle Fill="Red" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Panel.ZIndex="13"
Margin="12,34"
/>
<Rectangle Fill="Green" Width="100" Height="120"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="24,54"
/>
<Canvas>
<Rectangle Canvas.Left="5" Canvas.Top="5" Panel.ZIndex="2" Fill="Yellow" Width="120" Height="30" />
<Rectangle Canvas.Left="25" Canvas.Top="17" Panel.ZIndex="0" Fill="Blue" Width="120" Height="30" />
</Canvas>
</Grid>
</Window>
try this.
<StackPanel>
<Canvas>
<TextBlock Canvas.Left="10" Canvas.Top="6" Text="Choose a value from combobox:" Width="180"/>
<ComboBox Canvas.Left="190" Canvas.Top="4" Width="180"></ComboBox>
</Canvas>
</StackPanel>
RESULT:
How to create a hovered toolbar?
Clicking to expand the ToolBar will not shrink the Canvas.
Expander works for expanding, but the canvas will get shrinked.
<UserControl x:Class="smartgrid.studio.View.GraphicEditorView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:model="clr-namespace:smartgrid.studio.Model"
xmlns:studio="clr-namespace:smartgrid.studio"
xmlns:metro="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1000">
<DockPanel>
<Expander DockPanel.Dock="left" Header ="Toolbar" FontSize="18" ExpandDirection="Up">
<TreeView Name="GraphicEditorEntityTree" Background="Transparent" BorderBrush="Transparent" ItemsSource="{Binding GraphicEditorEntities}"/>
</Expander>
<Canvas/>
</DockPanel>
</UserControl>
You can overlay things by putting them in a Grid without rows or columns, the sizing of your toolbar is an independent matter (you can still use an expander for that).
http://msdn.microsoft.com/en-us/library/system.windows.controls.panel.zindex.aspx
Panel.ZIndex might be the solution.
<Grid x:Name="LayoutRoot">
<Grid x:Name="Toolbar" Panel.ZIndex="1000" Visibility="Collapsed">
</Grid>
<canvas />
</Grid>
I'm developing Windows Store App with using Caliburn Micro.
In one of the pages I have ContentControl, which display UserControl. In UserControl I have GridView. My question is: How to set UserControl.Width same as ContentControl.Width? Note: whet set UserControl.Width=Auto - width the same as GridView.Width
in page.xaml
<ContentControl x:Name="ActiveItem" />
in usercontrol.xaml
<UserControl
x:Class="Test.Views.GroupView"
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" Width="Auto" Height="Auto">
<Grid Margin="0,20">
<GridView x:Name="Groups" Margin="0" />
</Grid>
</UserControl>
UPDATE
Adding
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
To UserControl doesn't solve the problem.
Figured this out after a lot of trial and error:
<ContentControl Name="MyContent" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
The key is to use the Horizontal/Vertical*Content*Alignment property (not the Horizontal/VerticalAlignment properties).
Here is what you should do when problem like your's appears.
Try to set ContentControl's Background property to some disturbing color. For example Purple or Pink. And also set Background property on your UserControl for example Green. It will allow you to see where exactly is your ContentControl and where is UserControl. If you can't see any Green you can tell that content of UserControl is stretched to fill whole UserControl.
Try to set UserControl's VerticalAlignment and HorizontalAlignment properties to Stretch. FrameworkElement.HorizontalAlignment, VerticalAlignment
Note: In order to let these work. You can't explicitly set Width and Height on your UserControl.
Try to set ContentControl's VerticalContentAlignment and HorizontalContentAlignment to Stretch. Control.HorizontalContentAlignment, VerticalContentAlignment . These stretches the child element to fill the allocated layout space of the parent element.
If you still see some Purple or Pink then something's wrong again :) you can check Margin/Padding MSDN
If it's still messed up. Then I don't know how else can I help you. Last possible solution would be binding. And I am not sure if it works.
<UserControl
Width="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type ContentControl}},
Path=ActualWidth}"
Height="{Binding RelativeSource=
{RelativeSource FindAncestor,
AncestorType={x:Type ContentControl}},
Path=ActualHeight}">
...
</UserControl>
I hope something helps. I believe you that it could be really annoying problem.
Especially for #AlexeiMalashkevich
I solve it with using binding like this:
In root Page you have:
<ContentControl x:Name="ActiveItem"/>
Then add the child page:
<Page
Height="{Binding ActualHeight, ElementName=ActiveItem}"
Width="{Binding ActualWidth, ElementName=ActiveItem}"
......
/>
And that's all.
You should be able to bind UserControl's width to the ContentControl's ActualWidth.
<local:MyUserControl1 Height="50" Width="{Binding ElementName=contentControl, Path=ActualWidth}"/>
Here is some sample code:
<Page
x:Class="stofUserControlWidth.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:stofUserControlWidth"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="Cyan"/>
<ContentControl Grid.Column="1" x:Name="contentControl">
<local:MyUserControl1 Height="50" Width="{Binding ElementName=contentControl, Path=ActualWidth}"/>
</ContentControl>
</Grid>
</Page>
Here is MyUserControl1.xaml code:
<UserControl
x:Class="stofUserControlWidth.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:stofUserControlWidth"
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 Background="Magenta">
</Grid>
</UserControl>
Hope this helps!
For me this is working:
<UserControl
...
Height="{Binding ActualHeight,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentControl}}}">
...
</UserControl>
You have to make sure that your ContentControl has the desired size.
For example my ContentControl look like this: It is always fill the whole size of the window. And the size of the UserControl in the ContentControl dinamically changes as well.
<Grid>
<ContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" DataContext="{Binding StartViewModel}" Name="ContentArea" />
</Grid>