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
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 working with the MaterialDesign Icon pack which has a single XAML with a bunch of Canvas items declared such as:
<Canvas x:Key="appbar_3d_obj" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="40" Height="40" Fill="{DynamicResource BlackBrush}" Canvas.Left="18" Canvas.Top="18" Stretch="Fill" Data="F1 M 18,21.7037L 43.9259,18L 58,25.4074L 58,54.2963L 32.8148,58L 18,49.1111L 18,21.7037 Z "/>
</Canvas>
Then in the MainWindow.xaml I have:
<Button Content="{DynamicResource appbar_3d_obj}" Margin="55,400,707,21" />
The issue I have is that while they render properly after compiling, in the Designer you can't see them as the stroke is transparent / undefined. I could set Fill="Black" in the Icons.xaml file, but it seems I should learn how to do it the right way :)
How can I set the color so I can see the icons during design time?
Hard to know how to answer for sure with the small code example you posted but have you tried simply defining the BlackBrush in the resources for either the the MainWindow's XAML (or the Canvas's)?
<Window ...>
<Window.Resources>
<SolidColorBrush x:Key="BlackBrush" Color="Black"/>
</Window.Resources>
...
</Window>
This is my XAML:
<Window x:Class="IPCapture.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:IPCapture"
mc:Ignorable="d"
Title="IPCapture_GUI" Opacity="0.95" Background="Transparent" Foreground="White" FontFamily="Arial" FontSize="14" FontWeight="Bold" FontStretch="UltraExpanded" TextOptions.TextFormattingMode="Display" BorderThickness="0"
Loaded="Window_Loaded" WindowStartupLocation="CenterScreen" Height="Auto" Width="Auto" Cursor="Arrow" WindowStyle="None" AllowsTransparency="True" MouseLeftButtonDown="Window_MouseLeftButtonDown" Topmost="True" ResizeMode="CanResizeWithGrip">
<Window.OpacityMask>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="Black"/>
<GradientStop Color="#B2420000" Offset="1"/>
</LinearGradientBrush>
</Window.OpacityMask>
<Border CornerRadius="5" Background="#FFC20C0C" HorizontalAlignment="Left" VerticalAlignment="Top" Width="Auto" Height="Auto">
<Grid x:Name="GridMain" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0">
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Keys" Width="Auto"/>
<ColumnDefinition x:Name="Values" Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
<Border.Effect>
<DropShadowEffect Opacity="0.6" BlurRadius="1"/>
</Border.Effect>
</Border>
</Window>
I followed many tutorials on how to achieve the GUI I wanted and I finally succeeded! However, it does not seem to provide the functionality that I need. I want to:
Resize the width of the GUI
A visualisation of my problem:
The large faded blue area is my Window and the small GUI in the top-left corner of that is my actual widget.(That is enclosed in the Border)
As you can see from my code, I have set ResizeMode="CanResizeWithGrip" on the Window. I am able to resize the window perfectly fine BUT resizing it does not resize my actual GUI.(Because of how my XAML is laid out)
So, for this reason, I want to somehow allow resize on the width of the border instead of the Window.
Additions: (if possible)
Is it possible to remove that small black toolbar that's centered on the top of the Window?
I am also confused as to why, because I have set Height and Width of the Window to Auto, is it so large? Shouldn't it only expand as large as it's content?
Let's take it one at a time:
The resize issue is because of HorizontalAlignment="Left" VerticalAlignment="Top" you've set on the Grid and the Border. It means the element will measure its minimum required width & height and align to the top left. If you remove this, the element will (assuming there are no other layout issues) resize to contain the entire window.
Setting Auto for Width and Height (which is the default, by the way) behaves differently on a window - it tells the OS - not WPF - to determine the initial size (using an undisclosed algorithm, so don't rely on it). If you want WPF to resize the window to the minimum required by its content, set SizeToContent="WidthAndHeight".
The small black toolbar is a new VS 2015 feature and only appears during debugging. You can turn it off in the Live Visual Tree panel in VS.
Bonus tips:
I strongly discourage you from applying an Effect on the entire visual tree. It's a huge performance hit. You should look into using SystemDropShadowChrome.
Same goes for OpacityMask. Just use a uniform Opacity unless you really need that gradient... Even then you may be better off using a uniform opacity and a gradient brush as the background.
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.
I have Topmost fullscreen window
AllowsTransparency="True" WindowStyle="None" Topmost="True" WindowState="Maximized" Left="0" Top="0"
OpacityMask="#2B000000" Background="Black" Cursor="Cross"
and I'm drawing rectangle when user holds LMB and moves mouse (it's selection, like on screenshot in this my question Easiest way to select screen region ).
I want to make rectangle completely transparent, to see content behind window. But I can't make it more transparent than parent window. What should I do?
Try something like below and dynamically change the size and location of the second RectangleGeometry (selectRect) in some mouse event handler. And perhaps also adjust the size of the first RectangleGeometry to your screen size.
<Window x:Class="TransparentRectangle.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStyle="None" WindowState="Maximized"
AllowsTransparency="True" Background="Transparent">
<Grid>
<Path Fill="Black" Opacity="0.5">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry x:Name="screenRect" Rect="0,0,2000,2000"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<RectangleGeometry x:Name="selectRect" Rect="100,100,200,100"/>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
</Grid>
</Window>
A problem might however be that you won't get any mouse events in the excluded part of the CombinedGeometry. To avoid that you could attach the mouse handlers to the Window (instead of the Path) and give it a nearly transparent background.
<Window ... Background="#01000000" MouseMove=... etc>
...
</Window>
EDIT: An even simpler solution might be a Border. You could independently adjust the four components of the BorderThickness.
<Grid ...>
<Border BorderBrush="Black" Opacity="0.5" BorderThickness="100,100,200,400"/>
</Grid>