On button hover, enable ResizeMode - wpf

I am trying to make window frame appear when user hovers "mybutton". This should work but for some reason it is not. What am I missing?
<Window x:Class="test2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStyle="None" Loaded="ShellWindow_SourceInitialized" x:Name="mywindow">
<Window.Resources>
<Style TargetType="{x:Type Window}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsMouseOver, ElementName=mybutton}" Value="True">
<Setter Property="ResizeMode" Value="CanResize" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsMouseOver, ElementName=mybutton}" Value="False">
<Setter Property="ResizeMode" Value="NoResize" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid Name="mygrid" Loaded="Grid_Loaded">
<Button Name="mybutton" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
</Grid>
(In case you are wondering what those "Loaded" functions are, they remove chrome while keeping the shadow and allowtransparency=false
http://marcin.floryan.pl/blog/2010/08/wpf-drop-shadow-with-windows-dwm-api)
At the end it will not be button but will react on whole window border (I can not find better way to enable resizing while removing all chrome)

In the style TargetType should be MainWindow
<Style TargetType="{x:Type local:MainWindow}">
where local has to be mapped to your namespace:
xmlns:local="clr-namespace:test2"

myButton is defined after style. XAML parser is not that smart. User the following XAML to get your intended behavior:
<Window x:Class="test2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStyle="None" Loaded="ShellWindow_SourceInitialized" x:Name="mywindow">
<Grid Name="mygrid" Loaded="Grid_Loaded" >
<Button Name="mybutton" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75"/>
</Grid>
<Window.Style>
<Style TargetType="{x:Type Window}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=IsMouseOver, ElementName=mybutton}" Value="True">
<Setter Property="ResizeMode" Value="CanResize" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=IsMouseOver, ElementName=mybutton}" Value="False">
<Setter Property="ResizeMode" Value="NoResize" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Style>
</Window>

Related

Adding custom styles to icons inside Title bar of MetroWindow

I am using MahApps.Metro in my WPF app. The default behavior of the title bar of its MetroWindow is that any icon inside it has low opacity (dimmed) display unless you mouseover the icon. Even if you don't mouseover the icon, I would like to look it the same as when you mouseover it. How can we achieve this?
With mouseover on CupCakes icon [I would like it to look the same even without mouseover]:
Without mouseover:
MetroWindow.xaml:
<mah:MetroWindow x:Class="WPF_Mah_Metro_Test.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:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_Mah_Metro_Test"
mc:Ignorable="d"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
Height="450" Width="800">
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button x:Name="btnTest" Click="btnTest_Click" ToolTip="Open up the GitHub site">
<iconPacks:PackIconModern Width="22" Height="22" Kind="SocialGithubOctocat" />
</Button>
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<Button x:Name="btnTest1" Click="btnTest1_Click" Content="Deploy CupCakes">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Width="22" Height="22" VerticalAlignment="Center" Kind="FoodCupcake" />
<TextBlock Margin="4 0 0 0" VerticalAlignment="Center" Text="{Binding}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
<Grid>
</Grid>
</mah:MetroWindow>
To override the styles of the inner controls of the WindowCommands you must create your own style for it:
<Style x:Key="Styles.WindowCommands.Custom"
BasedOn="{StaticResource MahApps.Styles.WindowCommands}"
TargetType="{x:Type mah:WindowCommands}">
<Style.Resources>
<ResourceDictionary>
<Style BasedOn="{StaticResource MahApps.Styles.Button.WindowCommands}" TargetType="{x:Type Button}">
<Setter Property="Opacity" Value="1" />
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.ToggleButton.WindowCommands}" TargetType="{x:Type ToggleButton}">
<Setter Property="Opacity" Value="1" />
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="1" />
</Trigger>
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.SplitButton.WindowCommands}" TargetType="{x:Type mah:SplitButton}">
<Setter Property="Opacity" Value="1" />
</Style>
<Style BasedOn="{StaticResource MahApps.Styles.DropDownButton.WindowCommands}" TargetType="{x:Type mah:DropDownButton}">
<Setter Property="Opacity" Value="1" />
</Style>
</ResourceDictionary>
</Style.Resources>
</Style>
Now if you put this key to your `App.xaml you can use it in your App like:
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands Style="{StaticResource Styles.WindowCommands.Custom}">
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands Style="{StaticResource Styles.WindowCommands.Custom}">
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
Another solution could be to make a style for the Button directly.
Note: Namespace for mah is xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"

Cannot set trigger within TabControl template in WPF

I wrote a style for my TabControl. Within the TabControl I have a TextBlock and a Button. I wish to set trigger for TabItem.IsSelected such that the font colour of the text within TextBlock changed. My code below doesn't work:
<Style x:Key="_tabItemButtonStyle" BasedOn="{StaticResource MetroTabItem}" TargetType="{x:Type TabItem}">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Name="_TabHeaderStackPanel" >
<TextBlock Text="{ Binding TabName }" Name="_TabHeaderText" Background="{ Binding TabBackColour }" FontSize="{ Binding TabFontSize }" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=TabItem}}"
Value="True">
<Setter Property="Foreground" Value="SteelBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
...
The problem I suspect is with this code:
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=TabItem}}"
Value="True">
<Setter Property="Foreground" Value="SteelBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
EDIT:
I bind my tab items to a Collection of ViewModels. So my style binding looks as following:
<TabControl x:Name="_MainTabControl" Grid.Column="1" Grid.Row="1"
SelectedIndex="0"
ItemsSource="{Binding OpenTabs}"
ItemContainerStyle="{StaticResource _tabItemButtonStyle}" />
I don't know what MetroTabItem is. But the other Code looks fine.
I tried it out with sample Code. And it does exactly what you describe you want to achieve.
Please check whether your Styles are correctly applied with Style={StaticResource YourStyleName} on the TabItem
Here 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"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
</Window.Resources>
<Grid>
<Grid.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type TabItem}" x:Key="TestStyle">
<Setter Property="HeaderTemplate">
<Setter.Value>
<DataTemplate>
<StackPanel Name="_TabHeaderStackPanel" >
<TextBlock Text="test" Name="_TabHeaderText" Background="{ Binding TabBackColour }" FontSize="{ Binding TabFontSize }" >
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected,
RelativeSource={RelativeSource AncestorType=TabItem}}"
Value="True">
<Setter Property="Foreground" Value="SteelBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<Button Content="Test"></Button>
</StackPanel></DataTemplate></Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</Grid.Resources>
<TabControl>
<TabItem Style="{StaticResource TestStyle}">
</TabItem>
<TabItem Style="{StaticResource TestStyle}">
</TabItem>
</TabControl>
</Grid>

WPF Changing the style of a UserControl in a ListView

I'm having issues setting the style of my UserContorl. I have the UserControl called BusyIndicator defined in a file. Below is the xaml.
<UserControl x:Class="Foo.Client.UI.SVGs.BusyIndicator"
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="300" d:DesignWidth="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
>
<UserControl.Template>
<ControlTemplate>
<Border Width="{Binding Width}" Height="{Binding Height}" Visibility="{TemplateBinding Control.Visibility}">
<Canvas Width="{Binding Width}" Height="{Binding Height}" Visibility="{TemplateBinding Control.Visibility}">
<Path Fill="{Binding Foreground}"
Height="25"
Width="25"
Data="M20.519,4.617c-3.262-3.111-7.821-3.965-12.03-2.236 c-4.282,1.76-6.895,5.654-6.863,10.227l3.658-0.025C5.263,9.51,7.017,6.892,9.894,5.71c2.81-1.154,5.85-0.598,8.037,1.456 l-1.395,1.376h5.39V3.227L20.519,4.617z"/>
</Canvas>
</Border>
</ControlTemplate>
</UserControl.Template>
</UserControl>
I then reference the UserControl and use it in a ListView. The object the ListView is binding to has a property named Status. When Status is set to "Running", I'd like to change the style. When I run it, the Button is hidden so I know the Status property is notifying properly. But the svg:BusyIndicator control remains unchanged.
<UserControl x:Class="Foo.Views.Screens.CollectionResultsView"
AutomationProperties.AutomationId="CollectionResultsView"
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"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:svg="clr-namespace:Foo.Client.UI.SVGs;assembly=Foo.Client.UI"
d:DesignWidth="700">
<ListView ItemsSource="{Binding TargetStatusView}">
<StackPanel>
<Button>
<TextBlock Text="X"></TextBlock>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Running">
<Setter Property="Visibility" Value="Hidden" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<svg:BusyIndicator Width="25" Height="25">
<svg:BusyIndicator.Style>
<Style TargetType="svg:BusyIndicator">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Running">
<Setter Property="Visibility" Value="Hidden"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
</svg:BusyIndicator>
</StackPanel>
</ListView>
</UserControl>
I also tried to change the TargetType to UserControl but that didn't work either.
<svg:BusyIndicator Width="25" Height="25">
<UserControl.Style>
<Style TargetType="UserControl">
<Setter Property="Visibility" Value="Visible" />
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Running">
<Setter Property="Visibility" Value="Hidden"/>
<Setter Property="Foreground" Value="White" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Style>
</svg:BusyIndicator>
Setting <svg:BusyIndicator Width="25" Height="25" Visibility="Hidden"> does work but if I add <Setter Property="Visibility" Value="Hidden" /> to the style, above <Style.Triggers>, it does not work.
I also tried other properties like Opacity and Height without success.
What am I missing?
The issue was with the way we defined the BusyIndicator control. Because DataContext was set to {Binding RelativeSource={RelativeSource Self}}. With this, when it was used in the ListView, the context was the control itself and not the data bound to the ListView. So Binding="{Binding Status}" did work because the BusyIndicator usercontrol doesn't have a Status prooperty.
We updated the control below and it worked.
<UserControl x:Class="Foo.Client.UI.SVGs.BusyIndicator"
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="300" d:DesignWidth="300">
<Canvas>
<Path Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=Foreground}"
Data="M20.519,4.617c-3.262-3.111-7.821-3.965-12.03-2.236 c-4.282,1.76-6.895,5.654-6.863,10.227l3.658-0.025C5.263,9.51,7.017,6.892,9.894,5.71c2.81-1.154,5.85-0.598,8.037,1.456 l-1.395,1.376h5.39V3.227L20.519,4.617z">
</Path>
<Path Fill="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=Foreground}" Data="M4.733,20.634c3.26,3.111,7.82,3.964,12.03,2.234c4.281-1.76,6.894-5.652,6.862-10.227l-3.658,0.025c0.021,3.073-1.733,5.69-4.61,6.872c-2.808,1.155-5.85,0.598-8.037-1.457l1.396-1.375H3.324v5.315L4.733,20.634z" >
</Path>
</Canvas>
</UserControl>

Datatrigger in WPF

I am new to WPF, and learning the basics of WPF. What I want is when a CheckBox is checked then make the background of a Button green.
The following is to code I have written:
<Window x:Class="MyApplication.DataTrigger2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DataTrigger2" Height="300" Width="300" Loaded="Window_Loaded">
<Window.Resources>
<Style x:Key="styleDataButton" TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding chk}" Value="checked">
<Setter Property="Background" Value="Gold"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button x:Name="btn" Height="50" Width="100" Content="Button" Margin="89,33,89,178" Style="{StaticResource styleDataButton}"/>
<CheckBox x:Name="chk" Content="Checkbox" Height="50" Width="100" Margin="89,106,89,105"></CheckBox>
</Grid>
</Window>
You need to bind to CheckBox element. Binding="{Binding chk}" means that you are binding to "chk" property of the DataContext. You should change it to:
<DataTrigger Binding="{Binding ElementName=chk, Path=IsChecked}" Value="True">
<Setter Property="Background" Value="Gold"/>
</DataTrigger>
That way, you are binding to IsChecked property of your CheckBox and checking if value is true.

xaml how to create a trigger isMouseHover on TextBlock

How to create a trigger, which if mouse hover that textblock, the text will change color.
just try this with background or foreground
<TextBlock Text="Hello" Height="20">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="TextBlock.Background" Value="red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<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="350" Width="525">
<Window.Resources>
<Style x:Key="TextBlockMouseOverStyle" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<TextBlock Background="Blue" Style="{StaticResource TextBlockMouseOverStyle}" Text="Foo" />
</Grid>
</Window>

Resources