I found here that the DropShadows can't overflow over component with a fixed Height.
I tried to add somme ClipToBounds="False" in every containers but it doesn't seems to work.
you will see the problem if you create a new project with this code :
<Window .... >
<StackPanel x:Name="Sp2" Margin="20" Height="47" ClipToBounds="False">
<Rectangle Height="40" Fill="Purple" Margin="4" ClipToBounds="False">
<Rectangle.Effect>
<DropShadowEffect Opacity=".4" BlurRadius="13" ShadowDepth="4" Direction="288"/>
</Rectangle.Effect>
</Rectangle>
</StackPanel>
</Window>
Here is a screenshot of the problem :
On the left that's what i want, a shadow overflowing on a fixed height component, and on the right that's what i have.
As I work in a team and I'm developping every UI components for our application and I'd like other people of my team not to have to pay attention to these kind of details. How can we avoid this behavior, and if we can't what would be the guidelines to avoid this clipping effect ?
You can override GetLayoutClip() to stop most things clipping.
As explained here.
http://drwpf.com/blog/2007/12/28/cliptoboundsmaybe/
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace wpf_99
{
public class NoClipStackPanel : StackPanel
{
protected override Geometry GetLayoutClip(Size layoutSlotSize)
{
return ClipToBounds ? base.GetLayoutClip(layoutSlotSize) : null;
}
}
}
Markup
<Grid>
<local:NoClipStackPanel x:Name="Sp2" Margin="20" Height="47" ClipToBounds="False">
<Rectangle Height="40" Fill="Purple" Margin="4" ClipToBounds="False">
<Rectangle.Effect>
<DropShadowEffect Opacity=".4" BlurRadius="13" ShadowDepth="4" Direction="288"/>
</Rectangle.Effect>
</Rectangle>
</local:NoClipStackPanel>
</Grid>
One possibility to solve this issue is similar to solution of another problem, when trying to apply effects to control containing text and text become blurred. The idea is to detach effect, by applying it to something else, while ensuring that visually it looks like effect was applied to where you need it.
In your case you can do something like this:
<Grid>
<Rectangle Width="{Binding ActualWidth, ElementName=rect}"
Height="{Binding ActualHeight, ElementName=rect}"
Fill="Green">
<Rectangle.Effect>
<DropShadowEffect ShadowDepth="30" />
</Rectangle.Effect>
</Rectangle>
<StackPanel Margin="20" Height="47">
<Rectangle x:Name="rect" Height="40" Fill="Purple" Margin="4">
<!-- remove effect from here -->
</Rectangle>
</StackPanel>
</Grid>
The effect is not anymore on nested rectangle, but on some element (I've used Rectangle) which is added below StackPanel (since its transparent) in visual tree. If you do it like this than shadow can now extend itself to whole grid (which takes whole window size).
Related
BACKGROUND: We are using light projectors to display our application. Light projectors can be used just like displays. Projectors, however induce distortions that are corrected using geometric warping. We create shaders using the Shader properties provided on the UIElement class in WPF to do the geometric corrective warping. We have a handle on all that.
PROBLEM: All UIElement visuals are properly corrected on the projector screen -- except on the WebView2 UIElement. I have come to the conclusion that the Effect property of the WebView2 class doesn't work.
THIS WORKS: (No Webview2)
<Grid>
<Rectangle x:Name="Grid0" Height="800" Width="1280">
<Rectangle.Fill>
<ImageBrush x:Name="ProjectorLut" />
</Rectangle.Fill>
</Rectangle>
<Canvas Height="800" Width="1280" >
<Image ImageSource="BoundToRenderBitmpapSource" Height="800" Width="1280"/>
<Canvas.Effect>
<local:CalibrationEffect>
<local:CalibrationEffect.Input2>
<VisualBrush Visual="{Binding ElementName=Grid0}" />
</local:CalibrationEffect.Input2>
</local:CalibrationEffect>
</Canvas.Effect>
</Canvas>
</Grid>
THIS DOESN'T WORK
<Grid>
<Rectangle x:Name="Grid0" Height="800" Width="1280">
<Rectangle.Fill>
<ImageBrush x:Name="ProjectorLut" />
</Rectangle.Fill>
</Rectangle>
<Canvas Height="800" Width="1280" >
<wv2:WebView2 Name="webView" Source="https://earth.google.com" Height="800" Width="1280" >
</wv2:WebView2>
<Canvas.Effect>
<local:CalibrationEffect>
<local:CalibrationEffect.Input2>
<VisualBrush Visual="{Binding ElementName=Grid0}" />
</local:CalibrationEffect.Input2>
</local:CalibrationEffect>
</Canvas.Effect>
</Canvas>
</Grid>
So I tried something different. I replaced the XAML code for WebView2 with an image class bound to a RenderTargetBitmap generated imagesource rendered by creating the RenderTargetBitmap imagesource in code behind. That doesn't work for me either.
QUESTION: How can I look at this problem differently or am I doing something I need to look at more deeply?
I am using Desptop WPF and I appreciate your help.
I am trying to create this in WPF (I realize I could just use an image, but I am trying to learn WPF):
(source)
This is what I have so far but it isn't producing the desired result, in that, the textbox seems completely hide the ellipse whereas it should simply have a transparent background:
<StackPanel>
<TextBlock HorizontalAlignment="Left" Margin="144,207,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<Ellipse HorizontalAlignment="Left" Height="52" Margin="142,189,0,0" Stroke="Black" VerticalAlignment="Top" Width="52"/>
</StackPanel>
You can put things like this in a viewbox to make scaling easier, something like this. You'll need to remove the stack panel, it's going to stack items one on top of the other which isn't what you're after here. I used a grid in this case.
<Viewbox Width="100" Height="100">
<Grid Width="20" Height="20">
<Ellipse Stroke="Black"/>
<TextBlock HorizontalAlignment="Center" Text="i" TextAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Viewbox>
Or you can use the unicode character: ⓘ
code 0x24D8
<TextBlock Text="ⓘ" FontSize="52" />
So a stackpanel will place the first item at the top, the second just below it, third below the second, and so forth. What you could do is use a Canvas or a Grid. Like the stackpanel, they are "Content Controls" and support placing multiple objects inside of them like you have done with the stackpanel.
So a really quick way to do what you're trying to accomplish would be:
<Grid >
<Ellipse HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="52"/>
<TextBlock Text="i" FontSize="52" Margin="18,-13,-6,13" />
</Grid>
You can do it using a border and a TextBlock. A square border will become a circle if you make its CornerRadius equals half its Width (or Height):
<Border Width="100" Height="100" CornerRadius="50" BorderBrush="Black" BorderThickness="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="50" Foreground="Blue" >i</TextBlock>
</Border>
Don't use a StackPanel for this, the purpose of it is to stack things, not show them overlapped, you're using the wrong tool for that. Use a Grid, it's far more suited for what you're trying to do.
To have a transparent background, you have to either set the TextBlock's Background property to Transparent, or set a null background.
Background={x:Null}
I am coding a kind of map (for a very simple game) which is (for now) an image.
I want the user to be able to scroll the image around and resize it.
I tried a lot around, and currently i am using the ViewportControl, and the XAML looks more or less like the following (see below).
I works as it does all i need - BUT the image itself can be scrolled within the ViewportControll without any boundaries. As a result the image scrolls away.
Question: is there any way to prevent the Viewportcontroll to scroll the image out of a specified region?
<ViewportControl x:Name="viewport" Height="600" Width="440">
<Canvas x:Name="ParentCanvas" Background="Red" MaxHeight="600" MaxWidth="440">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" Stretch="UniformToFill" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.Left="-200" Canvas.Top="-300" Width="1320" Height="1800">
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>
After testing around i have a solution for my problem.
The most important part is to add the Bounds-tag to the ViewportControl as you can see below.
The scrolling is then handled by the ViewportControl itself. The pinch-gesture must be done manually, but it is possible, because the events will reach the correct UI-Element (here: the image).
In the example below, i used the Windows Phone Toolkit to handle the event more easily.
<ViewportControl x:Name="viewportCtrl" ScrollViewer.VerticalScrollBarVisibility="Visible" VerticalContentAlignment="Center" Bounds="0,0,1320,1800">
<Canvas x:Name="ParentCanvas" Background="Red" Height="1000" Width="800">
<Image x:Name="MapImage" Source="/Artwork/map.png" RenderTransformOrigin="0.2,0.2" >
<Image.RenderTransform>
<CompositeTransform x:Name="transform" />
</Image.RenderTransform>
</Image>
<Canvas x:Name="BlueCanvas" Top="100" Left="200" Background="Blue" Height="180" Width="180"></Canvas>
<tk:GestureService.GestureListener>
<tk:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
</tk:GestureService.GestureListener>
</Canvas>
</ViewportControl>
I would like to add shadows outside tiles in my WPF application, but when I do, the text inside tiles is blurry. I tried this solution: WPF DropShadowEffect Causing Blurriness , but unfortunately shadow effect seems not to work at all. Are there any special attributtes in Rectangle which should be set? Could you give me some clues?
i got the same issue and solved this by using UseLayoutRounding="True"
EDIT
<Grid UseLayoutRounding="True" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.Effect>
<DropShadowEffect ShadowDepth="0"
Color="Black"
BlurRadius="20" />
</Grid.Effect>
<!-- your content -->
<Grid Background="White">
<TextBlock Text="Test" FontSize="20" Margin="10" />
</Grid>
</Grid>
results this
hope that helps
Is it somehow possible to have somekind of a blurred border when scrolling? For better understanding I added a picture of what I want to acchieve.
The restriction that I have is, that underneath the ScrollViewer I have got a background Image. Thus, I cant just use a filled Rectangle with white to transparent gradient at the left side of the ScrollViewer.
Since WinRT dropped support for OpacityMask and I'm not sure if you'd want to set it with an Alpha channel. With that said though, there's pretty much always a work around. So what if you just utilize the natural z-order instead and fake it? Something like this;
<!-- Grid as Container -->
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<!-- example backgrounds, like images, just for the concept example. -->
<StackPanel Orientation="Horizontal">
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
<Rectangle Height="75" Width="300" Fill="Red" Margin="20,0"/>
</StackPanel>
</ScrollViewer>
<!-- An adhoc gradient overlay to just float over the ScrollViewer itself.
Then using Margin to fit it to the shape of the Scrollviewer and still
allow hit visibility to the scrollbar etc. -->
<Rectangle Width="50" HorizontalAlignment="Left" Margin="1,1,0,20">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,0.5" StartPoint="0.1,0.5">
<GradientStop Color="White" Offset="0.3"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
</Grid>
Of course you'll probably want to tweak some values like the Rectangle Margin in the example to make it look exactly right with your own setup, but the concept should be there and is an option. Hope this helps.