Remove shadow effect when window is maximised in wpf - wpf

I had an window with styles
Background="Transparent", AllowsTransparency="True", WindowStyle="None", ResizeMode="NoResize".
I had placed custom min, max, close buttons and implemented functionality.And as i want the window to resize the window on all the sides. i implemented it with HwndSource which works fine. Now my concern is i want shadow effect for the window.so i placed the border with shadow effect like this.
<Border CornerRadius="5" Margin="10">
<Border.BitmapEffect>
<DropShadowBitmapEffect ShadowDepth="10" Opacity=".5" Softness="9" />
</Border.BitmapEffect>
<Grid> **Content over here**</Grid>
</Border>
window gets the shadow effect. but when i maximise the window. it does not fit to the screen as i had added border. i need to remove the shadow effect when window is maximized so that it fit to the screen. and the shadow effect should appear when window is in not in maximized state. how to get this or is there any another method to get this.. please help me to find the solution.

I think it would be possible to add/remove the shadow effect dynamically in the code by creating style for your Border. You can create a style for your border something like this:
<Style x:Key="borderstyle" TargetType="Border">
<Setter Property="BitmapEffect">
<Setter.Value>
<DropShadowBitmapEffect ShadowDepth="10"> </DropShadowBitmapEffect>
</Setter.Value>
</Setter>
</Style>
And then set it dynamically in the code
borderelement.Style =(Style)Application.Current.MainWindow.Resources["borderstyle"];
and remove it by using the following code
borderelement.Style = null

You can use a trigger to determine if Window is maximized and then in the trigger setter, remove the effect. Just overload template for the Window and inside ControlTemplate triggers add a trigger
<Window.Template>
<ControlTemplate TargetType="Window">
<Border x:Name="brd">
<Border.Effect>
<DropShadowEffect BlurRadius="20" Color="Black"/>
</Border.Effect>
<Grid Width="200" Height="200" MouseDown="Grid_MouseDown_1" Background="Red"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="WindowState" Value="Maximized">
<Setter Property="Effect" TargetName="brd" Value="{x:Null}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Template>

Related

Round the corners of a button in Window.Resources WPF

I am very new to WPF. I've familiarized myself with ControlTemplate, ContentPresenter, and some other pieces, but I am struggling to create a button with rounded corners as defined from Window.Resources (or potentially a separate style file).
Anyways, when I add this to a <Button/> tag, I get a button with rounded corners:
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Button.Resources>
However, when I try to include it up in the Window.Resources the button will not apply the border style:
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Grid>
<Rectangle Fill="{TemplateBinding Background}" Stroke="{TemplateBinding Foreground}"/>
<Border CornerRadius="5"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
This doesn't look right to me, but I guess I don't know where to add the specification of CornerRadius such that it will apply to the button. I did see this post, How to create/make rounded corner buttons in WPF? but it's a little over my head. I just want to round all the buttons in my application!
The Border in your ControlTemplate is not visible, because you have neither set its Background, nor its BorderBrush.
You could have something like shown below. Note however that with a simple ControlTemplate like this a Button loses all the visualizations of its states, like focused, mouse-over, pressed etc.
<ControlTemplate x:Key="roundbutton" TargetType="Button">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
CornerRadius="5">
<ContentPresenter/>
</Border>
</ControlTemplate>
You may instead just declare a default Button Style (i.e. a Style resource without x:Key) that applies your original Border Style like this:
<Style TargetType="Button">
<Style.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Style.Resources>
</Style>

WPF: decide where to show the contentPresenter in your User control

I have a very simple UserControl with some borders and some decorations that react to mouseOver, pressed and some nice things.
I want to allow people to set the content of the text from outside, but when I set the content, the generated content presenter overwrites my whole WPF structure.
This is what I tried so far:
<UserControl tags tags tags>
<!-- This is the only way I found to style the textblock that WPF -->
<!-- generates to encapsulate the content string -->
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<TextBlock Background="Green"
HorizontalAligment="Center"
VerticalAlignment="Center"
Text = "{TemplateBinding Content}"/>
</ControlTemplate>
</UserControl.Template>
<!-- Here my borders and fancy things. I want to add animations -->
<!-- and react to mouseOver and Pressed like a button -->
<Border x:Name="SuperNiceBorder" tag tag tag>
<HERE I WANT THE CONTENTPRESENTER>
</Border>
</UserControl>
Is there a way to tell WPF I want the text set by the user in the Content just there ???
Move all your animations and triggers inside the ControlTemplate.
Replace your TextBlock with a ContentPresenter:
<UserControl x:Class="MySolution.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Border x:Name="MyBorder" Background="Green">
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content = "{TemplateBinding Content}"/></Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="MyBorder" Property="Background" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</UserControl.Template>
</UserControl>
And you can use the UserControl like these examples:
1:
<local:MyControl Content="Test Testing tester"/>
2:
<local:MyControl>
<TextBlock Text="Another test from a TextBlock"/>
</wpfAllPurposesTest:MyControl>

How to determine on which side ContextMenu opens?

Let's say i got this ContextMenu:
<Style x:Key="{x:Type ContextMenu}" TargetType="{x:Type ContextMenu}">
<Setter Property="VerticalOffset" Value="-10"/>
<Setter Property="HorizontalOffset" Value="-10"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ContextMenu}">
<Border Background="Transparent">
<Border.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="0" Opacity="0.5"/>
</Border.Effect>
<Border Margin="10" Style="{StaticResource MenuBorderStyle}">
<Grid x:Name="SubMenu" Grid.IsSharedSizeScope="True">
<!-- StackPanel holds children of the menu. This is set by IsItemsHost=True -->
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Grid>
</Border>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
So as you can see, i offset the appearance of the menu by 10 pixels to the top and to the left, getting the top-left corner of the ContextMenu to be right under the cursor.
In fact, because of Border's margin of 10 pixels, the whole control shoule be more left-top than a cursor, because the control it self starts with a shadow.
And, as you can have guessed, when the context menu appears not on the bottom-right side of the cursor (say the cursor is near bottom or left side of the screen), the offset needs to be changed to an opposite (by either either X or Y or both coordinates).
The question is how to do that by xaml?
(sorry for my english)
Try setting Placement property to AbsolutePoint. Check this out as well, it might help you.

Setter in property trigger fails if target property already has an explicit value

I'm currently trying to create a ControlTemplate for the Button class in WPF, replacing the usual visual tree with something that makes the button look similar to the little (X) close icon on Google Chrome's tabs. I decided to use a Path object in XAML to achieve the effect. Using a property trigger, the control responds to a change in the IsMouseOver property by setting the icon's red background.
Here's the XAML from a test app:
<Window x:Class="Widgets.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<Style x:Key="borderStyle" TargetType="Border">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#CC0000"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<ControlTemplate x:Key="closeButtonTemplate" TargetType="Button">
<Border Width="12" Height="12" CornerRadius="6"
BorderBrush="#AAAAAA" Background="Transparent"
Style="{StaticResource borderStyle}"
ToolTip="Close">
<Viewbox Margin="2.75">
<Path Data="M 0,0 L 10,10 M 0,10 L 10,0" Stroke="{Binding BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType=Border, AncestorLevel=1}}" StrokeThickness="1.8"/>
</Viewbox>
</Border>
</ControlTemplate>
</Window.Resources>
<Grid Background="White">
<Button Template="{StaticResource closeButtonTemplate}"/>
</Grid>
</Window>
Note that the circular background is always there - it's just transparent when the mouse isn't over it.
The problem with this is that the trigger just isn't working. Nothing changes in the button's appearance. However, if I remove the Background="Transparent" value from the Border object in the ControlTemplate, the trigger does work (albeit only when over the 'X').
I really can't explain this. Setters for any other properties placed in the borderStyle resource work fine, but the Background setter fails as soon as the default background is specified in the ControlTemplate.
Any ideas why it's happening and how I can fix it? I know I could easily replace this code with, for example, a .PNG-based image, but I want to understand why the current implementation isn't working.
Thanks! :)
Try moving the explict "Background" assignment from inside the Border declaration to the Style itself:
<Style x:Key="borderStyle" TargetType="Border">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#CC0000"/>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
...
<Border Width="12" Height="12" CornerRadius="6"
BorderBrush="#AAAAAA"
Style="{StaticResource borderStyle}"
ToolTip="Close">
Styles can't override a property that has been explicitly set. You need to set the value in the style.
I think your problem is that the Border does not 'catch' the mouse events when it is transparant.
To verify - try changing the background to #01FFFFFF instead of Transparent.

how do i make that dang wpf popup go away?

when i use a popup, it seems to hang around. in the code below i attach a popup to a textBox using by overriding the control template, and make the popup appear when the TextBox has focus. When you tab to the next on screen element the popup goes away, but if you just alt-tab to a different application the popup stays there in the foreground. how do i get rid of it?
<Window x:Class="DropDownPicker.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<StackPanel>
<TextBox Text="hello">
<TextBox.Style>
<!-- Simple TextBox -->
<Style
TargetType="{x:Type TextBox}">
<Setter
Property="KeyboardNavigation.TabNavigation"
Value="None" />
<Setter
Property="FocusVisualStyle"
Value="{x:Null}" />
<Setter
Property="AllowDrop"
Value="true" />
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type TextBox}">
<Grid>
<Border
x:Name="Border"
Background="{DynamicResource WindowBackgroundBrush}"
BorderBrush="{DynamicResource SolidBorderBrush}"
BorderThickness="1"
Padding="2"
CornerRadius="2">
<Grid>
<!-- The implementation places the Content into the ScrollViewer. It must be named PART_ContentHost for the control to function -->
<ScrollViewer
Margin="0"
x:Name="PART_ContentHost"
Style="{DynamicResource SimpleScrollViewer}"
Background="{TemplateBinding Background}" />
<Popup
x:Name="thePopup"
IsOpen="False">
<Border
BorderBrush="Red"
BorderThickness="5">
<TextBlock
Text="Hellssss" />
</Border>
</Popup>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger
Property="IsFocused"
Value="True">
<Setter
TargetName="thePopup"
Property="IsOpen"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TextBox.Style>
</TextBox>
<TextBox
Text="ssss" />
</StackPanel>
</Grid>
</Window>
Have you tried setting the StaysOpen property to False?
If StaysOpen is True, which is the default, it will stay open until the control is no longer in focus. If it is False it will stay open until a mouse or keyboard event occurs outside of the Popup control, which may be the case while alt-tabing. You might have to tweak it a bit to get it to behave like you want, but it may be a starting point.
I listened to the LostMouseCapture event and then set the StaysOpen property on the Popup to false
This is by-design; Window focus != Control focus, otherwise when you tabbed away from a window and came back, your cursor would jump back to the first control. If you want the pop up to be hidden when the window isn't active, you have to manually do this.
Similar question is asked here also:
WPF Popup ZOrder
Check this:
http://chriscavanagh.wordpress.com/2008/08/13/non-topmost-wpf-popup/
Hope this help you!!

Resources