WPF Buttons with Paths as Content - c#

I ran into an interesting thing and I can't figure out how to fix it at the moment, maybe I'm missing something really simple.
I'm re-designing some of the UI but I'm not really experienced with it right now.
So I have 3 buttons and I wanted to draw patterns as the content of the buttons instead of using images.
I have managed to do so(still needs tweaking), but the buttons on hover event only triggers once my pointer enters the pattern area instead of the area of the button. Does anyone mind taking a look at it please?
<Button Grid.Column="0" Width="35" Height="35"
Command="{StaticResource MinimizeCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
Background="{x:Null}" BorderBrush="{x:Null}">
<Path Data="M20,14H4V10H20" VerticalAlignment="Center"
HorizontalAlignment="Center" Height="2.6"
Margin="7,20,7,10" Stretch="Fill" Width="16">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource MainForeColor}"/>
</Path.Fill>
</Path>
</Button>
Code : https://hastebin.com/kofaqehoti.xml

By setting the background and the border brushes of the buttons to null the button will only be clickable and detectable for hover where the paths are drawn. Replace the nulls with Transparent or #00000000 and the buttons will be invisible but clickable/hoverable (If that's a word)
<Button Grid.Column="0" Width="35" Height="35"
Command="{StaticResource MinimizeCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"
Background="Transparent" BorderBrush="#00000000">
<Path Data="M20,14H4V10H20" VerticalAlignment="Center" HorizontalAlignment="Center" Height="2.6" Margin="7,20,7,10" Stretch="Fill" Width="16">
<Path.Fill>
<SolidColorBrush Color="{DynamicResource MainForeColor}"/>
</Path.Fill>
</Path>
</Button>

Related

How to achieve the Adobe XD background blur effect in WPF [duplicate]

I am trying to create a blur effect in WPF, but I want to blur the content located behind the control (such as a Grid), I do not intend to blur the contents of the Grid.
I want to do something like this image.
If you are looking for something like this:
The answer is to use a BitmapEffect :
<Image Source="http://www.pingminghealth.com/wp-content/uploads/2010/12/cherries.jpg" Stretch="UniformToFill">
<Image.BitmapEffect>
<BlurBitmapEffect Radius="20" />
</Image.BitmapEffect>
</Image>
You can find a tutorial about it on msdn: How to Apply a Blur Effect to a Visual.
Just in case, someone is still looking for a solution in 2018, something like this worked for me: BlurryControls.BlurryUserControl.cs
<Rectangle>
<Rectangle.Effect>
<BlurEffect Radius="{DynamicResource BlurRadius}"/>
</Rectangle.Effect>
<Rectangle.Fill>
<VisualBrush
ViewboxUnits="Absolute"
Viewbox="{Binding RenderTransform.Children[3],
Converter={StaticResource TranslateTransformToRectViewboxVisualBrushConverter},
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}},
UpdateSourceTrigger=PropertyChanged}"
AlignmentX="Left" AlignmentY="Top"
Visual="{Binding ElementName=BackgroundContainer}" Stretch="None">
<VisualBrush.Transform>
<TranslateTransform X="0" />
</VisualBrush.Transform>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>

Blur background in WPF

I am trying to create a blur effect in WPF, but I want to blur the content located behind the control (such as a Grid), I do not intend to blur the contents of the Grid.
I want to do something like this image.
If you are looking for something like this:
The answer is to use a BitmapEffect :
<Image Source="http://www.pingminghealth.com/wp-content/uploads/2010/12/cherries.jpg" Stretch="UniformToFill">
<Image.BitmapEffect>
<BlurBitmapEffect Radius="20" />
</Image.BitmapEffect>
</Image>
You can find a tutorial about it on msdn: How to Apply a Blur Effect to a Visual.
Just in case, someone is still looking for a solution in 2018, something like this worked for me: BlurryControls.BlurryUserControl.cs
<Rectangle>
<Rectangle.Effect>
<BlurEffect Radius="{DynamicResource BlurRadius}"/>
</Rectangle.Effect>
<Rectangle.Fill>
<VisualBrush
ViewboxUnits="Absolute"
Viewbox="{Binding RenderTransform.Children[3],
Converter={StaticResource TranslateTransformToRectViewboxVisualBrushConverter},
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}},
UpdateSourceTrigger=PropertyChanged}"
AlignmentX="Left" AlignmentY="Top"
Visual="{Binding ElementName=BackgroundContainer}" Stretch="None">
<VisualBrush.Transform>
<TranslateTransform X="0" />
</VisualBrush.Transform>
</VisualBrush>
</Rectangle.Fill>
</Rectangle>

Common layout in WPF application

I am new to WPF an creating a application where I want to make a generic layout which could be applied for all windows.I want few buttons and window properties to be comman on all windows.
Please help if this is possible.I am unable to find any link or source where this sort of functionality is explained.
Many Thanks.
*****Edit****
I am using this code which shows a button on window.I dont want to write it on all windows.I want to place in base/parent so that it appears on all windows which i add to project and inherit from the base/parent class.
But How? I have got very little idea.Any help is appreciated.
<Controls:MetroWindow.RightWindowCommands>
<Controls:WindowCommands>
<Button Content="settings" Name="Settings" Click="Settings_Click" />
<Button>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" Visual="{StaticResource appbar_cupcake}" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="test" />
</StackPanel>
</Button>
</Controls:WindowCommands>
</Controls:MetroWindow.RightWindowCommands>
Yes you can do it.. there is a term called UserControl you have to write your own UserControl.
For basic how to write re-usable UserControl. check the given link
Its not the control you want.. but you can get an idea how to write UserControl.. :)
For creating a common theme for the whole application you should look in the direction of Styles and Shared Resources, see here http://msdn.microsoft.com/en-us/library/ms745683(v=vs.110).aspx
Or you can use ready-made Themes, like here http://wpfthemes.codeplex.com/
EDIT
You can achieve this by moving the common controls which should be used in all windows to a separate UserControl. So then you will have smth like this:
UserControl
<StackPanel>
<Button Content="settings" Name="Settings" />
<Button>
<StackPanel Orientation="Horizontal">
<Rectangle Width="20" Height="20" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}">
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill" />
</Rectangle.OpacityMask>
</Rectangle>
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="test" />
</StackPanel>
</Button>
</StackPanel>
Then to all the windows where you need these controls you should add this control, like this:
<local:UserControl1 x:Name="myCtrl"></local:UserControl1>
where local is the namespace where the UserControl1 is defined.

How do I reference top UIElement in ControlTemplate?

In my custom control I have ControlTemplate propety
public ControlTemplate ControlTemplate
It can be something like this:
<map:IdattMapLayer.ControlTemplate>
<ControlTemplate>
<Canvas
DataContext="{Binding
Converter={StaticResource ObjectToTrackedAssetConverter}}">
<Button
Style="{StaticResource LooklessButtonStyle}"
Width="{Binding PushpinWidth}" Height="{Binding PushpinWidth}"
Margin="{Binding PushpinMargin}"
Command="{Binding
Path=DataContext.SelectedPushpinChangedCommand,
ElementName=LayoutRoot}"
CommandParameter="{Binding}"
Cursor="Hand">
<Ellipse
Width="{Binding PushpinWidth}"
Height="{Binding PushpinWidth}"
Stroke="Black"
Fill="{Binding IsGPSDataRecent,
Converter={StaticResource BoolToGreenRedBrushConverter}}"
StrokeThickness="1">
</Ellipse>
</Button>
</Canvas>
</ControlTemplate>
</map:IdattMapLayer.ControlTemplate>
I would like to set Canvas's data context myself rather than doing it in XAML.
So, If I have ControlTemplate - how do I find first child (Canvas in this case) programmatically?
1) set x:Name attribute for Canvas.
2) override OnApplyTemplate.
3) use (Canvas)GetTemplateChild("CanvasName") for get Canvas.
ofcourse this class should inherit from Control.

WPF Window - Fade Different parts of the same window

I have a basic WPF windows with the markup as specific below:
<Window x:Class="Application.SomeWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SomeWindow"
Topmost="True" WindowStyle="None" Height="39" Width="400"
ResizeMode="NoResize" ShowInTaskbar="False"
WindowStartupLocation="Manual" Background="Transparent"
Closing="Window_Closing" AllowsTransparency="True" Opacity="0">
<Border Background="CornflowerBlue" BorderBrush="Black" BorderThickness="0,0,0,0" CornerRadius="5,5,5,5" Opacity="0.75">
<Grid>
<!-- Display bar -->
<Image Grid.Row="1" Height="24" Margin="7,7,0,0" Name="img1" Stretch="Fill" VerticalAlignment="Top" Source="/Application;component/Images/dashboard/1.png" HorizontalAlignment="Left" Width="13" />
<Image Height="24" Margin="19,7,47,0" Name="image21" Source="/Application;component/Images/dashboard/2.png" Stretch="Fill" VerticalAlignment="Top" Grid.Row="1" Grid.ColumnSpan="2" />
<!-- Button 1 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,25,0" Name="btn1" Click="btn1_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="1">
<Image Height="26" HorizontalAlignment="Right" Name="img1" Source="/Application;component/Images/dashboard/3.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
<!-- Button 2 -->
<Button Style="{DynamicResource NoChromeButton}" Height="27" Margin="0,5,5,0" Name="btn2" Click="btn2_Click" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" Width="23" ToolTip="2">
<Image Height="26" HorizontalAlignment="Right" Name="img2" Source="/Application;component/Images/dashboard/4.png" VerticalAlignment="Top" Width="22" Stretch="Fill" />
</Button>
</Grid>
</Border>
</Window>
Here is what it looks like now:
What I'd really like to do is make it so that initially looks like this:
Then, once mouseover happens, to fade background opacity in from 0 so it looks like the first image. The problem is that if I set the Border or Grid Background color to Transparent with the goal of fading in on mouseover, then everything inside the Border or Grid is affected as well.
Is there a way to manage the opacities of window and its UI elements seperately? Or perhaps there is a totally different route to take to get this background fade on mouseover? Thanks.
There are two options. Number one is to just move the outer border inside the grid, as the first child (and have the other controls alongside it, not in it). That way it will fade by itself, but still be behind the other controls. You will of course either have to set ColumnSpan/RowSpan, or wrap the entire thing in another Grid.
The second option is to just fade the background, not the entire border:
<Border ...>
<Border.Background>
<SolidColorBrush Color="CornflowerBlue" Opacity="0.5"/>
</Border.Background>
...
try this trick - draw a rectangle or border with dimensions bind to parent or ElementName.
It won't affect rest of elements of tree. Works for me.
<Grid x:Name="abc">
<Border
Width="{Binding ActualWidth, ElementName=abc}"
Height="{Binding ActualHeight, ElementName=abc}"
Background="Blue"
Opacity="0.5"/>
//buttons or inner grid
...
</Grid>
If you don'w want to use ElementName, simply replace Width and Height by
Width="{Binding ActualWidth, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"
Height="{Binding ActualHeight, Source={RelativeSource Mode=FindAncestor, AncestorType=Grid}}"

Categories