Wpf Dropshadow remove offset - wpf

Is there a way to set shadow effect with 0 offset?
It's ugly when I set this effect on a border. I am trying to reproduce the box-shadow css property
Here a sample of code to have some context:
<Border
BorderThickness="1,0,0,1"
Grid.Column="1"
Grid.Row="0"
>
<Border.Effect>
<DropShadowEffect Direction="360" ShadowDepth="5" />
</Border.Effect>
...
</Border>

Try something like this:
<DropShadowEffect ShadowDepth="3" BlurRadius="3" Opacity="0.5" />
You probably want to give your Border some margin too, else the shadow will expand further than you want

Set ShadowDepth to 0, this can remove offset completely.
<DropShadowEffect ShadowDepth="0" BlurRadius="12" Opacity="1" Color="Red" />
ShadowDepth controls offset size, and Direction controls angle
<DropShadowEffect Direction="180" BlurRadius="12" ShadowDepth="12" Color="red"/>

Related

WPF create thumbnail by VisualBrush

I have a user control for display thumbnail of a window
UserControl XAML :
<Grid x:Name="containerGrid" Margin="0">
<Border Background="White" CornerRadius="5">
<Border.Style>
<Style>
<Style.Triggers>
<Trigger Property="Border.IsMouseOver" Value="True">
<Setter Property="Border.Effect">
<Setter.Value>
<DropShadowEffect BlurRadius="20" Color="White" ShadowDepth="0" />
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</Border.Style>
<Border x:Name="containerBorder" CornerRadius="5" BorderThickness="1" BorderBrush="Black">
<Border.Background>
<VisualBrush x:Name="vb" />
</Border.Background>
</Border>
</Border>
</Grid>
Once a new window been created, I let above user control display thumbnail of window content by VisualBrush
vb.Visual = (Border)Win.Template.FindName("mainBorder", Win);
Everything seems work fine...
Opened Window
Thumbnail
Until the window size changed by user...
Thumbnail
My question is how should I do to let thumbnail width and height always fits my user control (200 X 200) no matter how source(window) size changed??
Many thanks if there is any clue.
SOLVED by set Stretch to Fill and ViewBox to window ActualWidth and ActualHeight
<VisualBrush x:Name="vb" Stretch="Fill" ViewboxUnits="Absolute">
<VisualBrush.Viewbox>
<MultiBinding Converter="{CONV:WidthHeightToRectConverter}">
<Binding Path="Win.ActualWidth" />
<Binding Path="Win.ActualHeight" />
</MultiBinding>
</VisualBrush.Viewbox>
</VisualBrush>
You could try setting stretch on your visualbrush.
<VisualBrush Stretch="Fill"
There are other options on stretch but I think Fill will be the one you want.

Border.Background Effect

I have been trying Microsoft.Expression.Media.Effects to create a MonoChromeEffect on UIElements.
xmlns:e="http://schemas.microsoft.com/expression/2010/effects"
<Border.Effect>
<e: MonochromeEffect Color="Blue" />
</Border.Effect>
This works fine for any control with any Color.
My problem is when attempting to apply to an ImageBrush. (adding blue mono-tint to just the background).
<Border.Background >
<ImageBrush ImageSource="{Binding WaterMarkImage}"
Stretch="UniformToFill" Opacity=".34"
RenderOptions.BitmapScalingMode="HighQuality"
AlignmentX="Center" AlignmentY="Top" />
</Border.Background>
This will colorize all controls inside the Border - (including for instance - ListBoxItems to mono-blue).
Is there anyway to just affect just the ImageBrush - (not the list items - (keep them White)?
You may use a VisualBrush with an Image control instead of an ImageBrush and apply the effect to the Image:
<Border.Background>
<VisualBrush>
<VisualBrush.Visual>
<Image ImageSource="{Binding WaterMarkImage}"
Stretch="UniformToFill" Opacity=".34" ...>
<Image.Effect>
<e:MonochromeEffect Color="Blue"/>
</Image.Effect>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Border.Background>

Creating button with specific geometry XAML

Please can anyone suggest a solution of my problem.
Most "custom buttons" on different tutorials based on standard geometry forms (triangle, rectangle, circle etc.) anв changed only their appearance.
I trying to create button with specific geometry and changed it on mouse event.
what I have:
I created style where diskribe
I created a polygon in the form of a rectangle with rounded corners (this is important)
I created style where described my custom button, and in main window i added the Style attribute:
<Button Width="40" Margin="5,0,5,-15" DockPanel.Dock="Right" HorizontalAlignment="Right" Background="{x:Null}" BorderBrush="{x:Null}" Height="40" Style="{StaticResource ResourceKey=PLCButtonStyle}"/>
this is how i described geometry:
</Style.Resources>
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}" >
<Grid>
<MAIN:RoundedCornersPolygon Name="Border" Points="0,0 75,0 75,15 75,30 0,30 "Stretch="Fill"
StrokeThickness="1" ArcRoundness="5" UseRoundnessPercentage="False" Stroke="Black" IsClosed="True
<MAIN:RoundedCornersPolygon.Fill>
<RadialGradientBrush RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3" >
<GradientStop Color="lightgray" Offset="0" />
<GradientStop Color="black" Offset="1" />
</RadialGradientBrush>
</MAIN:RoundedCornersPolygon.Fill>
</SCADA:RoundedCornersPolygon>
I need to animate the transition of certain points of the polygon from one coordinate to another.
from Points="0,0 75,0 75,15 75,30 0,30 "
to Points="0,0 60,0 75,15 60,30 0,30 "
what i need to do for this?

Setting width and height properties to auto in WPF causes button to blur

When I was testing a new interface for a button I noticed a blur appearing during run-time that was not present during design-time. I tracked it down to the auto property.
The image below displays to button during run-time the left has its height and width set to auto and the right has its height and width set manually. As you can see there is a blur on the left button.
Why is this caused? Is there any way of getting round it?
Thanks.
Relevent XAML:
<Border Padding="1,1,1,1" Height="Auto" Width="Auto">
<!-- Border Properties -->
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="8"/>
</Border.Effect>
<Border.Background>
<SolidColorBrush x:Name="BorderBrush" Color="Gray"/>
</Border.Background>
<!-- End Properties -->
<!-- Children -->
<Grid>
<!-- Properties -->
<Grid.Background>
<LinearGradientBrush x:Name="BackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop x:Name="BackgroundLightColor" Color="#FF282828" Offset="0.572"/>
<GradientStop Color="#FF3C3C3C" Offset="0"/>
</LinearGradientBrush>
</Grid.Background>
<!-- End Properties -->
<!-- Children -->
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}" Margin="20,5,20,5">
<TextBlock.Foreground>
<SolidColorBrush x:Name="ForegroundBrush" Color="#FFBBBBBB"/>
</TextBlock.Foreground>
</ContentPresenter>
<!-- End Children -->
</Grid>
<!-- End Children -->
</Border>
</ControlTemplate>
<!-- End Template -->
Left Button:
<Border Padding="1,1,1,1" Height="auto" Width="auto">
Right Button:
<Border Padding="1,1,1,1" Height="29" Width="72">
It looks like a subpixel rendering issue, try setting SnapsToDevicePixels or UseLayoutRounding on your application or control.

WPF clipping even when no clipping is desired - how to turn it off?

I need to float out some content out of the ListBox as specified in a DataTemplate for an ListBox.ItemTemplate. I am using RenderTransform but the content gets clipped on ListBox boundaries. ClipToBounds is False for the entire visual tree.
I have read somewhere that WPF internally performs some clipping even when none is specified with dedicated clipping properties. I have also found out that using Canvas can sometimes cure the clipping problem but it does not help here.
How can I overcome this problem? Here is some XAML that I want to fix. Please note the entire left part of rectangle is missing.
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform X="-50" />
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ListBox.ItemTemplate>
42
</ListBox>
The ListBoxItem's are getting clipped by the ScrollViewer in the ListBox Template. To work around this I think you'll need to remove the ScrollViewer from the Template and if you need scrolling you can wrap the ListBox in a ScrollViewer
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ListBox Margin="100,10,0,0">
<ListBox.Template>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="1" SnapsToDevicePixels="true">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemTemplate>
<DataTemplate>
<Rectangle Fill="Red" Stroke="Green" StrokeThickness="4" Width="100" Height="50">
<Rectangle.RenderTransform>
<TranslateTransform X="-50" />
</Rectangle.RenderTransform>
</Rectangle>
</DataTemplate>
</ListBox.ItemTemplate> 42
</ListBox>
</ScrollViewer>
Update
The ScrollViewer in the Template will generate a ScrollContentPresenter which in turn has the following GetLayoutClip
protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
return new RectangleGeometry(new Rect(base.RenderSize));
}
This class is Sealed so you can't derive from it to override this method. You would have to implement your own ScrollContentPresenter (e.g MyScrollContentPresenter) and probably your own ScrollViewer that uses MyScrollContentPresenter as well to make this work (and if you return null in this method I think that some items below the bounds of the ListBox could become visible as well)
I stumbled upon a solution to this problem by accident while working around it. If you change the ScrollViewer's HorizontalScrollMode and VerticalScrollMode to "Disabled" within the style template, it will stop clipping in each direction respectively.
Edit: May not work for WPF. I tested with a UWP app. The fields in question are:
ScrollViewer.HorizontalScrollMode="Disabled"
ScrollViewer.VerticalScrollMode="Disabled"

Resources