xaml ScrollViewer, blurred border - Windows Store App - c#

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.

Related

Using SkiaSharp to create crossed out circle filled with color

I am new to working with skiasharp with avalonia. I looked at the documentation and examples of how to make some basic shapes, like circles, rectangles, etc. Can anyone give advice or suggestion on how to make a crossed circle filled with color? I think it would be best to do UserControl, something like in wpf.
How you package this up (UserControl) really depends on the use case and intention of the UI element.
<Viewbox x:Name="Vol2"
Width="25"
Height="25">
<Canvas Width="100" Height="100">
<Ellipse x:Name="MyCirlce" Width="100" Height="100" Fill="Black">
</Ellipse>
<Rectangle Height="50" Fill="White" Width="15" Canvas.Top="50" Canvas.Left="42.5" RenderTransformOrigin="0,0">
<Rectangle.RenderTransform>
<RotateTransform Angle="45"></RotateTransform>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
</Viewbox>
A ViewBox scales it's content, like an SVG.
We then plop a Canvas in there and add our Ellipse. We then add a Rectangle and position in (Left, Right) and then add a RotateTransform.
This should get you going.

How to use Webview2.Effect

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.

How to overflow a shadow from a fixed Height container

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).

Create borderbrush "around the border path"

I'm trying to create a border with a gradient stroke around the border path, not around the full element but around the border itself.
A simple example of what I do not want is:
<Border BorderThickness="10" Width="100" Height="50">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="Black" Offset="0.5"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Border.BorderBrush>
</Border>
This creates a border that looks like:
What I to achieve wish is something like the image below. Notice that this achieved by blurring, I rather not do that as that would limit the what can be done - and more importantly: it would either blur all child elements, or I'd lose the ability to walk the visual tree with the border at the expected position. (Border would be a sibbling to its "content")
Dig a bit into shadow of border it looks closer
<Border BorderThickness="5" Width="100" Height="50" CornerRadius="5" BorderBrush="Gray">
<Border.Effect>
<DropShadowEffect BlurRadius="20" Opacity="1" ShadowDepth="1" Color="Black">
</DropShadowEffect>
</Border.Effect>
</Border>
It will give you something like
Alternatively
you can draw Blured dummy border on the same place with the current one (Bind width and height), but lower in the markup, in that case UI will draw dummy border over your container border and you'll see bluring without harming the tree
<Border BorderThickness="0" Width="100" Height="50" CornerRadius="5" BorderBrush="Gray" x:Name="x">
<TextBox Width="70" Height="20">Some data</TextBox>
</Border>
<Border BorderThickness="5" Width="{Binding Width, ElementName=x}" Height="{Binding Height, ElementName=x}" CornerRadius="0" BorderBrush="Black">
<Border.Effect>
<BlurEffect Radius="10"></BlurEffect>
</Border.Effect>
</Border>
If you really want to be able to have a blurred gradient border i think you might have to go with something like this.
Create a trapeze-shape with your gradient:
Then copy this shape 3 times and apply some render-transformations to get the border shape
Apply a Blur Effect on the whole shape
I made all those screenshots directly from the WPF result.

Tile background - black spaces between tiles

I wanted to experiment with image background of my WPF app. I downloaded a few textures, but unfortunately I have a problem.
Here's my XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="458" Width="473">
<Window.Background>
<VisualBrush TileMode="Tile" Viewport="0,0,0.5,0.5" Stretch="None">
<VisualBrush.Visual>
<Image Source="Images/binding_dark.png" Stretch="None">
<Image.OpacityMask>
<ImageBrush ImageSource="Images/binding_dark.png" Stretch="None" TileMode="Tile"/>
</Image.OpacityMask>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Window.Background>
<Grid>
</Grid>
</Window>
It's just an empty window, but that's just to see better what the issue is.
Here's the result:
I wanted to get a nice texture as a background of my app, but for some reason the images do not align with each other - there is this strange black spacing between them. What's the reason for this?
//EDIT
Just to clarify:
I'd like to have a background built of many of tiled copies of the same image - not one imgage filling the whole window
To get tiled background without space between you need to add: Stretch="Uniform"
Also you should set Viewportunits to Absolute and size. Change 32 to size of your Image in code below:
ViewportUnits="Absolute" Viewport="0,0,32,32"
Full code:
<Window.Background>
<ImageBrush ImageSource="/TestApp;component/Images/bg.png" ViewportUnits="Absolute" Viewport="0,0,32,32" Stretch="Uniform" TileMode="Tile" />
</Window.Background>
Try to set the background of the grid, not the window, like this:
<Grid>
<Grid.Backgroud>
<ImageBrush Source="Images/binding_dark.png" x:Name="image" Stretch="UniformToFill"/>
</Grid.Background>
</Grid>
You can set the background of the whole window but i'm not sure that this is a good practice

Categories