Blur effect on image as a window background - wpf

I have a window in my WPF app with an image as a background. I want that image to be blurred. This is how I do it:
This is my window:
<Window x:Class="kiosk.UI.Views.PageSwitch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:myProjectName.Converters"
Title="PageSwitch" Height="1024" Width="1280"
Style="{StaticResource WindowStyle}"
WindowStyle="None" ResizeMode="NoResize"
WindowStartupLocation="CenterScreen">
</Window>
And here's the style I apply to it:
<Style x:Key="WindowStyle" TargetType="{x:Type Window}">
<Setter Property="FontFamily" Value="Verdana" />
<Setter Property="Background">
<Setter.Value>
<VisualBrush>
<VisualBrush.Visual>
<Image Source="Images\myImage.png" >
<Image.Effect>
<BlurEffect Radius="20"/>
</Image.Effect>
</Image>
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Style>
This works - the image is blurred. However, there's a thick black border of about 5 mm around the background image. Why is it there and how can I remove it?
Here's what I tried as an alternative:
<VisualBrush Viewbox="0, 0, 1280, 1024" ViewboxUnits="Absolute" >
and the border is removed but the image is stretched a lot. Almost half of the image isn't even shown.
How can I fix this?

Do it like shown in this answer to one of your previous questions. Put the Image control in a Grid with ClipToBounds set to true.
<VisualBrush>
<VisualBrush.Visual>
<Grid ClipToBounds="True">
<Image Source="Images\myImage.png">
<Image.Effect>
<BlurEffect Radius="20"/>
</Image.Effect>
</Image>
</Grid>
</VisualBrush.Visual>
</VisualBrush>

I do a similar thing but just add the image as a element to the LayoutRoot. From this I set the margin to minus out the blur radius to avoid blurring in edges. If you're black border fades in I would suspect this is the issue.
<Image Source="pack://siteoforigin:,,,/image.jpg" Stretch="UniformToFill" Margin="-50">
<Image.Effect>
<BlurEffect Radius="100"/>
</Image.Effect>
</Image>

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.

Make form semi transparent to see form's background image

I'm using WPF (c#) form with background image (background imagebrush).
I want to make all the UI elements(button , title, textbox)... become semi-transparent so that they don't cover the image completely,
but the background image still being visible (not semi-transparent)
I would like a way we can do it without having to set all the opaque value of UI elements.
Maybe this could help
<Window.Resources>
<Style x:Key="transparentControls" TargetType="Button">
<Setter Property="Opacity" Value="0.1"/>
<Setter Property="Background" Value="Green"/>
</Style>
</Window.Resources>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="MyImage.jpg"/>
</Grid.Background>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" VerticalAlignment="Top" Content="Hey"/>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" Content="There"/>
<Button Height="24" Width="100" Style="{StaticResource transparentControls}" VerticalAlignment="Bottom" Content="Click Me"/>
</Grid>
Just try to put all your UI elements in a Canvas or Grid and set the Opacity of that parent element.
Like that:
<Canvas Opacity="1">
<Button Width="100" Height="100"></Button>
</Canvas>
I hope this was what you meant.

WPF: Textblock Font size should be even when its size change

I create a custom button in my application as following
<Button x:Class="MyApp.ButtonMainMenuSubCat"
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"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="536">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Grid Name="gridParent">
<Image Name="imgTransparent" Source="/MyApp;component/Resources/LeftCategoryTransparent.png" Stretch="Fill" Margin="0,0,0,0" />
<Image Name="Part_Pressed" Source="/MyApp;component/Resources/PressedMainScreenSubMenu.png" Stretch="Fill" Margin="0,0,0,4" Visibility="Hidden"/>
<Image Name="Focused" Source="/MyApp;component/Resources/MainSubMenuFocus.png" Margin="-3,0,-3,3" Stretch="Fill" Visibility="Hidden" />
<Image Name="Seperator" Source="/MyApp;component/Resources/MainSubMenuSeperator.png" Margin="5,0,5,-1" Stretch="Uniform" VerticalAlignment="Bottom"/>
<TextBlock Name="lblTitle" Text="{TemplateBinding Content}" HorizontalAlignment="Left" Foreground="Gray" FontWeight="{TemplateBinding FontWeight}" FontSize="24" Margin="10" VerticalAlignment="Center" TextWrapping="WrapWithOverflow" TextAlignment="Left"/>
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="True">
<!--<Setter TargetName="Pressed" Property="Visibility" Value="Visible"/>-->
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="Focused" Property="Visibility" Value="Visible"/>
<Setter TargetName="lblTitle" Property="Foreground" Value="#f8cb1c" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
In my application, I call web service and depending upon the no of items, i create button for each item and finally add these button in StackPanel. Its works well. Stakpanel layout is on left side in screenshot. Now problem is that when I run this application on different machine which have different Screen resolution (like 1920 *1200), then font size seems too small. So i want to adjust font size when container size change. One option is use ViewBox but in case of ViewBox all buttons seems like have different font size and TextWrapping is not possible.
So my actual requirement is that increase/decrease the textblock's font size with TextWrapping and font size must be even for all buttons.
You can use a LayoutTransform based on the screen resolution, you can either scale up your stackpanel or scale up the whole window depending on the resolution.
For the stackpanel:
<StackPanel>
<StackPanel.LayoutTransform>
<ScaleTransform x:Name="ScaleTransform" />
</StackPanel.LayoutTransform>
<Button>A</Button>
<Button>B</Button>
<Button>C</Button>
<Button>D</Button>
</StackPanel>
Then bind the ScaleX and ScaleY to a formula based on the resolution. An example of this:
double scale = System.Windows.SystemParameters.PrimaryScreenHeight / 720;
//using 720p as the base screen height.
this.ScaleTransform.ScaleX = scale;
this.ScaleTransform.ScaleY = scale;
You may want to do this in a ViewModel with some databinding if you are using MVVM.

WPF - Button on Image Moves at Run Time

I have a program that displays a grid that contains an image and 3 buttons. The buttons have been sized in the Visual Studio designer to fit inside separate circles (each approx 1/4" in diameter). When I run the program each of the buttons all move down and to the right about 1/2 the width of the button. If I add an explicit width and height to each button I can keep the size the same but the buttons still moves slightly to the right and maybe even down slightly.
My guess is that it has to do with how Windows has displayed the image to fit on the screen and that this scaling/positioning has not been applied to the buttons. If so, I have no idea how to correct the issue.
Any ideas on how to correct this problem would be greatly appreciated.
Chris
My XAML code:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Height}"
Width="{Binding Source={x:Static SystemParameters.WorkArea}, Path=Width}"
WindowStartupLocation="CenterScreen"
Background="CornflowerBlue"
ResizeMode="CanMinimize"
>
<Window.Resources>
<Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Black"/>
<Setter Property="Opacity" Value="1"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Cursor" Value="Hand"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Name="grid1">
<Image Name="image" Source="D:\CEP\Image1.jpg" Stretch="Uniform">
</Image>
<Button Margin="494,0,1155,801" Click="button_407_Click"></Button>
<Button Margin="339,107,1310,856" />
<Button Margin="401,102,1248,860" />
</Grid>
Set the Stretch property of the Image to None to prevent the image from sizing.
You have positioned the buttons by setting their margins. As soon as the window is resized their positions and sizes will change.
Add a Canvas to the grid and put the image and the buttons on the canvas using absolute positioning (Canvas.Left="..." Canvas.Top="..."
If, after doing this, you do not like the results because you still want to resize the the images and move the buttons in sync you could wrap the Canvas in a ViewBox to make it scale.
EDIT
<Grid>
<Viewbox>
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<Image Source="Images\wp_1680.jpg" Width="300" Height="200"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Canvas Width="300" Height="200"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Button Canvas.Top="25" Canvas.Left="50" Content="OK"/>
<Button Canvas.Top="125" Canvas.Left="150" Content="Cancel"/>
</Canvas>
</Grid>
</Viewbox>
</Grid>
This solution includes nice scaling through the Viewbox, but it can be removed as well.
Please organize all your posts. If you want to say something about my answer add it as a comment to my answer if you want add to your question, edit the question.

How to draw shape or lines within a WPF button that size to the control without cause the button to expand forever?

I had a quick Google, and a quick look around StackOverflow, but couldn't find anyone else who'd run into this problem.
I want to create a close button with a little X in it. The close button will do things like fade in and out when you're hovering over the item containing it, change colour when you mouse over, and all the usual WPF loveliness. Bottom line, it doesn't seem like it should be that difficult, but I'm running into one of the weirdest issues ever before I've even got to this stage.
Here's my XAML style for the button:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TabCloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Content">
<Setter.Value>
<Grid>
<Line Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"
X1="0"
Y1="0"
X2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualWidth, Mode=OneWay}"
Y2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualHeight, Mode=OneWay}"/>
<Line Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"
X1="0"
Y1="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualHeight, Mode=OneWay}"
X2="{Binding RelativeSource={RelativeSource AncestorType=Grid}, Path=ActualWidth, Mode=OneWay}"
Y2="0"/>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
And I create my button, just as a test, like this:
<Window x:Class="WpfTestApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="124" Width="569">
<Grid Background="#2b3c59">
<StackPanel Orientation="Horizontal">
<!-- Other controls removed for clarity -->
<Button Style="{DynamicResource TabCloseButtonStyle}"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Padding="2"
Margin="0, 10, 0, 0"
MinWidth="50"
MinHeight="50"></Button>
</StackPanel>
</Grid>
</Window>
And here's where it all goes horribly wrong. When you run the application the button will expand infinitely, one pixel at a time, horizontally, and vertically until it hits the height of the window.
Now I can understand why this is happening: the Lines actually go one unit beyond the width and height of the Grid causing the Grid to expand by one unit, then there's a relayout, the data binding causes the lines to redraw, ad infinitum.
So, to try and deal with this I decided to put a in the grid but then, no matter what I do with HorizontalAlignment and VerticalAlignment, I end up with both the Canvas and the Grid having zero width and height, which means I don't get my cross, which is massively irritating. If I bind to the ActualWidth and ActualHeight properties of the button I just end up with an X that has the top-left corner centred on the centre of the button.
Does anybody have any idea at all what I can do to fix this? I'd be extremely grateful for any pointers - WPF is still a rather new beast to me.
Thanks!
You shouldn't have to resort to bindings just to do layout. As you've seen, the bindings and the layout systems don't work in concert (I think databinding gets priority over layout, but in your case, layout causes another databinding)
You should be able get quite a nice looking, stretchable X with a just a Path:
<Path Data="M0,0 L1,1 M0,1 L1,0" Stretch="Uniform" Stroke="Red" />
If you want it to scale with the button size instead of stretch (scale affects apparent stroke width), then just use a ViewBox
Instead of binding, I'd suggest using the Stretch and Margin or Padding properties, like the following
<Grid Margin="2">
<Line X1="0" Y1="0" Y2="1" X2="1" Stroke="Black" Stretch="Fill" />
<Line Y1="1" X2="1" Stroke="Black" Stretch="Fill" />
</Grid>
Update
So the problem with your example seems to be the min height & width. If you can't just use height & width, I'd suggest something like the following
<Grid MinHeight="{TemplateBinding MinHeight}" MinWidth="{TemplateBinding MinWidth}">
<Line X1="0" Y1="0" Y2="1" X2="1" Stroke="Black" Stretch="Fill" />
<Line Y1="1" X2="1" Stroke="Black" Stretch="Fill" />
</Grid>
Thanks everyone. Rob's solution with the Viewbox turned out to be the answer. The button behaves perfectly, even if I remove the MidWidth and MinHeight attributes from the Button declaration in MainWindow.xaml.
Here's my modified style:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Style x:Key="TabCloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Content">
<Setter.Value>
<Grid>
<Viewbox>
<Path Data="M0,0 L10,10 M0,10 L10,0"
Stretch="Uniform"
Stroke="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground, Mode=OneWay}" />
</Viewbox>
</Grid>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
Thanks again for all the suggestions!

Resources