How to show/hide a panel - c#

When the mouse hover, the panel will be show on the left side and leave the mouse it will be hiden.
How to do that in WPF?
Is there any component?

Here's a slide-out console panel from one of my apps (I haven't included the style, but you get the idea). It starts with a width and height of zero, and expands when a toggle button is clicked (notice the EventTrigger that ties the slide-out animation to the Unchecked event of the Togglebutton).
If you base it on the mouseover event instead, that should help you on your way.
<!-- Console Panel -->
<Border Style="{StaticResource SettingsWindowStyle}" x:Name="ConsoleBorder" Grid.Row="0" Grid.Column="2" Margin="0,0,0,0">
<Border.Triggers>
<EventTrigger SourceName="toggleConsole" RoutedEvent="ToggleButton.Checked">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.2" Storyboard.TargetProperty="Width" To="635" />
<DoubleAnimationUsingKeyFrames BeginTime="0:0:0.2" Duration="0:0:0.3" Storyboard.TargetProperty="Height">
<LinearDoubleKeyFrame Value="680" KeyTime="0:0:0.2" />
<LinearDoubleKeyFrame Value="690" KeyTime="0:0:0.24" />
<LinearDoubleKeyFrame x:Name="FullScreenConsole" Value="700" KeyTime="0:0:0.3" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="toggleConsole" RoutedEvent="ToggleButton.Unchecked">
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames Duration="0:0:0.2" Storyboard.TargetProperty="Height">
<LinearDoubleKeyFrame Value="100" KeyTime="0:0:0.2" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:0.2" Duration="0:0:0.2" Storyboard.TargetProperty="Width">
<LinearDoubleKeyFrame Value="40" KeyTime="0:0:0.2" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
<Grid Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<ToggleButton Style="{StaticResource ToggleButtonStyle}" x:Name="toggleConsole">
<TextBlock Text="Console" Foreground="Black">
<TextBlock.LayoutTransform>
<RotateTransform Angle="90" />
</TextBlock.LayoutTransform>
</TextBlock>
<ToggleButton.ToolTip>
<ToolTip>
<TextBlock Padding="10" Background="White" Foreground="Black" Text="Show/Hide" />
</ToolTip>
</ToggleButton.ToolTip>
</ToggleButton>
<Rectangle Style="{StaticResource RectangleDividerStyle}" />
<DockPanel Grid.Column="0" Margin="10,2,0,2" Background="#33FFFFFF">
<StackPanel Orientation="Vertical" DockPanel.Dock="Top" Margin="0,10,0,0">
<!-- main screen box -->
<TextBox x:Name="txtConsole" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.CanContentScroll="True" Margin="5,0,0,0" Width="500" Height="590" HorizontalAlignment="Left" VerticalAlignment="Top"></TextBox>
<!-- button row -->
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="5,10,0,0">
<TextBox x:Name="txtSend" Width="400" Height="30" Margin="0,0,0,0" KeyDown="txtSend_KeyDown" >
</TextBox>
<Button Name="cmdSend" Click="cmdSend_Click" Width="80" Margin="3,0,0,0" Template="{StaticResource GlassButton}">
<TextBlock Foreground="LightGray">Send</TextBlock>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1" Margin="5,5,0,0">
<Button HorizontalAlignment="Left" Margin="5,2,0,0" Foreground="White" Height="30" x:Name="btnRawStatus" Click="btnRawStatus_Click" Width="100" Template="{StaticResource GlassButton}">Raw Status</Button>
<Button HorizontalAlignment="Left" Margin="5,2,0,0" Foreground="White" Height="30" x:Name="btnLast50" Click="btnLast50_Click" Width="100" Template="{StaticResource GlassButton}">Last 50 Logs</Button>
</StackPanel>
</StackPanel>
</DockPanel>
</Grid>
</Border>

Related

Adding isChecked binding to a custom ToggleSwitch

I have created a customer ToggleSwitch using this code and then changing the design to suit me.
WPF toggleswitch code
However when it loads on my page it looks like this:
I'm really new to this so i understand I've got a user based error that i literally dont understand however after hours I can't fix it!
I obviously need to make sure it loads with a checked value, however if I put isChecked ="true" in the xaml then it still loads like the unassigned picture.
In reality I have a setting "toggleDefault" in my code which I want to use on load of the form to say:
togContact = toggleDefault
However since I cant even get the XAML state to work, then this isnt working either.
Any suggestions would be great.
XAML custom code:
<Window.Resources>
<Style x:Key="myToggleSwitch" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Viewbox>
<Grid x:Name="toggleSwitch">
<Border x:Name="Border" CornerRadius="10"
Background="#FFFFFFFF"
Width="80" Height="25">
<Border.Effect>
<DropShadowEffect ShadowDepth="0.5" Direction="0" Opacity="0.3" />
</Border.Effect>
<Ellipse x:Name="Ellipse" Fill="#FFFFFFFF" Stretch="Uniform"
Margin="2 2 2 1"
Stroke="Gray" StrokeThickness="0.2"
HorizontalAlignment="Left" Width="22" >
<Ellipse.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="1" Opacity="0.3" Direction="260" />
</Ellipse.Effect>
</Ellipse>
</Border>
<TextBlock x:Name="txtOff" Text="OFF" Margin="0 0 8 0" VerticalAlignment="Center" FontWeight="DemiBold" HorizontalAlignment="Right" Foreground="White"/>
<TextBlock x:Name="txtOn" Text="ON" Margin="15 0 0 0" VerticalAlignment="Center" FontWeight="DemiBold" Foreground="White" HorizontalAlignment="Left"/>
</Grid>
</Viewbox>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Checked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#34A543"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="56 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0.0" To="1.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Unchecked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C2283B"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="2 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0" To="1.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
And below is my control code in the grid:
<ToggleButton x:Name="togContact" IsChecked="true" Margin="5" Grid.Column="2" Grid.Row="0" Height="20" Style="{StaticResource myToggleSwitch}" />
EDIT:
I have tried adding this to XAML:
IsChecked="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=IsChecked, Mode=TwoWay}"
This made no change.
I then tried setting isChecked to FALSE in the C# code.
This was interesting as it made the OFF appear in the UI on load.
I then tried changing isChecked to True in the c# code and i got an exception!
{"'Border' name cannot be found in the name scope of 'System.Windows.Controls.ControlTemplate'."}
So I have obviously stuffed up the custom togglebutton code...
This happens because the button is loading with the following styles:
<Grid x:Name="toggleSwitch">
<Border x:Name="Border" CornerRadius="10"
Background="#C2283B"
Width="80" Height="25">
<Border.Effect>
<DropShadowEffect ShadowDepth="0.5" Direction="0" Opacity="0.3" />
</Border.Effect>
<Ellipse x:Name="Ellipse" Fill="#FFFFFFFF" Stretch="Uniform"
Margin="2 2 2 1"
Stroke="Gray" StrokeThickness="0.2"
HorizontalAlignment="Left" Width="22" >
<Ellipse.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="1" Opacity="0.3" Direction="260" />
</Ellipse.Effect>
</Ellipse>
</Border>
<TextBlock x:Name="txtOff" Text="OFF" Margin="0 0 8 0" VerticalAlignment="Center" FontWeight="DemiBold" HorizontalAlignment="Right" Foreground="White"/>
<TextBlock x:Name="txtOn" Opacity="0" Text="ON" Margin="15 0 0 0" VerticalAlignment="Center" FontWeight="DemiBold" Foreground="White" HorizontalAlignment="Left"/>
</Grid>
To have the toggle button load as either ON or OFF, you need to change the background colour of the border in the toggle switch and also either set the txtOff or txtOn TextBlock to have an opacity of 0.
The button below will load as red and OFF 🙂
<Window.Resources>
<Style x:Key="myToggleSwitch" TargetType="{x:Type ToggleButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Viewbox>
<Grid x:Name="toggleSwitch">
<Border x:Name="Border" CornerRadius="10"
<!-- Background color here -->
Background="#C2283B"
Width="80" Height="25">
<Border.Effect>
<DropShadowEffect ShadowDepth="0.5" Direction="0" Opacity="0.3" />
</Border.Effect>
<Ellipse x:Name="Ellipse" Fill="#FFFFFFFF" Stretch="Uniform"
Margin="2 2 2 1"
Stroke="Gray" StrokeThickness="0.2"
HorizontalAlignment="Left" Width="22" >
<Ellipse.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="1" Opacity="0.3" Direction="260" />
</Ellipse.Effect>
</Ellipse>
</Border>
<TextBlock x:Name="txtOff" Text="OFF" Margin="0 0 8 0" VerticalAlignment="Center" FontWeight="DemiBold" HorizontalAlignment="Right" Foreground="White"/>
<!-- Opacity change here -->
<TextBlock x:Name="txtOn" Opacity="0" Text="ON" Margin="15 0 0 0" VerticalAlignment="Center" FontWeight="DemiBold" Foreground="White" HorizontalAlignment="Left"/>
</Grid>
</Viewbox>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Checked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#34A543"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="56 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0.0" To="1.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Unchecked">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="#C2283B"
Duration="0:0:0.1" />
<ThicknessAnimation Storyboard.TargetName="Ellipse"
Storyboard.TargetProperty="Margin"
To="2 2 2 1"
Duration="0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOff"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="0" To="1.0" Duration="0:0:0:0.1" />
<DoubleAnimation
Storyboard.TargetName="txtOn"
Storyboard.TargetProperty="(TextBlock.Opacity)"
From="1.0" To="0.0" Duration="0:0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>

I want To reuse the Style block of First Button for others button too, How should I do?

I write a simple code for MouseEnter effect for a button. There are also 2 other button where I want same effect. Instead of writing the same code again how can I reuse them?
<Button Content="Common Factor" FontSize="32" Foreground="White"
Background="#FF3399FF" Width="250" Height="60" Margin="20" >
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Width" To="300"/>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Height" To="80"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
<Button Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
To answer your question
You can declare your Style in a ResourceDictionary like this:
<Window.Resources>
<Style TargetType="Button" x:Key="MyButtonStyle">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Width" To="300"/>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Height" To="80"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
By giving a key to it (here, "MyButtonStyle"), you can then refer to it from other places using the StaticResource markup:
<Button Style="{StaticResource MyButtonStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
<Button Style="{StaticResource MyButtonStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
<Button Style="{StaticResource MyButtonStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
To go further with Styles
Note that if you don't specify an explict key to your Style by removing the x:Key="MyButtonStyle" markup, then your Style automatically applies to all Controls without an explicit Style property set. For example, a Style defined like this:
<Window.Resources>
<Style TargetType="Button">
<Style.Setters>
<Setter Property="Background" Value="Red"/>
</Style.Setters>
</Style>
</Window.Resources>
would automatically apply to all Buttons in the Window which don't have an epxlicit Style attribute.
You can store your Style in any resource dictionary object such as a MergedDictionary in App.xaml or Window.Resources:
<Window.Resources>
<Style TargetType="Button" x:Key="myStyle">
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Width" To="300"/>
<DoubleAnimation Duration="0:0:0.500" Storyboard.TargetProperty="Height" To="80"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
And reuse it by creating objects of type StaticResource:
<Button Style="{StaticResource myStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
<Button Style="{StaticResource myStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>
<Button Style="{StaticResource myStyle}" Content="Common Factor" FontSize="32" Foreground="White" Background="#FF3399FF" Width="250" Height="60" Margin="20"/>

start wpf animation from other element

how can I start this animation not at Window.Loaded event? I want to fire it at the click method of this button in the xaml.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button x:Name="myButton" Grid.Column="1" Height="25" Width="100">Start</Button>
<Canvas Name="Can1">
<Rectangle Name="Rect1" Canvas.Left="10" Fill="LightSeaGreen"
Stroke="Bisque"
StrokeThickness="5"
Width="100" Height="100">
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="Rect1"
Storyboard.TargetProperty="(Canvas.Left)"
From="10" To="100"
Duration="0:0:2"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
</Grid>
Move the Storyboard to the Button's Triggers, in an EventTrigger on the Button.Click event:
<Button x:Name="myButton" Grid.Column="1" Height="25" Width="100" Content="Start">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="Rect1"
Storyboard.TargetProperty="(Canvas.Left)"
To="100" Duration="0:0:2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Canvas x:Name="Can1">
<Rectangle x:Name="Rect1" Canvas.Left="10" Width="100" Height="100"
Fill="LightSeaGreen" Stroke="Bisque" StrokeThickness="5"/>
</Canvas>

Prevent GroupItem Headers from Scrolling Horizontally

I've got a DataGrid with grouped data where the GroupItem headers show to the left of the actual data rows as show below:
However, when you scroll horiztonally you can see that the group item headers also scroll to the point where they are no longer visible on the screen.
Is there anyway to prevent the GroupItem headers from scrolling?
Below is the xaml for the group style:
<Style x:Key="SeverityModificationFactorGroupItemStyle" TargetType="{x:Type GroupItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ControlTemplate.Resources>
<Storyboard x:Key="HoverOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Hover" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.2000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="HoverOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Hover" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="SelectedOn">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="select_gradient" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="SelectedOff">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="select_gradient" Storyboard.TargetProperty="(UIElement.Opacity)">
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid Background='Transparent' >
<Grid.ColumnDefinitions>
<ColumnDefinition Width='Auto' />
<ColumnDefinition Width='Auto' />
<ColumnDefinition Width='*' />
<ColumnDefinition Width='Auto' />
</Grid.ColumnDefinitions>
<Rectangle x:Name="BackgroundRectangle" Grid.ColumnSpan="4" Grid.RowSpan="2" Fill="{StaticResource NormalBrush}" Stretch="Fill" Stroke="{StaticResource NormalBorderBrush}" StrokeThickness="1" />
<Rectangle x:Name="Hover" Grid.ColumnSpan="4" Grid.RowSpan="2" Stretch="Fill" Fill="{StaticResource MouseOverBrush}" Opacity="0" />
<Border Margin="0,5,0,3">
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="160"/>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Grid.Column="0" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" Margin="0,-5,0,-3">
<CheckBox Grid.Column="0" IsChecked="{Binding Items[0].IsSelected}" HorizontalAlignment="Center" VerticalAlignment="Center"
Command="{Binding Path=DataContext.SetLayerYearLossTableIsSelectedCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding Items[0]}>
</CheckBox>
</Border>
<Border Grid.Column="1" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" Margin="0,-5,0,-3">
<TextBlock Grid.Column="1" Text="{Binding Items[0].YearLossTableName}" FontWeight="Bold" VerticalAlignment="Center" TextWrapping="Wrap"/>
</Border>
<Border Grid.Column="2" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" Margin="0,-5,0,-3">
<CheckBox Grid.Column="2" IsChecked="{Binding Items[0].IsInuring}" HorizontalAlignment="Center" VerticalAlignment="Center"
Command="{Binding Path=DataContext.SetIsInuringCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding Items[0]}">
</CheckBox>
</Border>
<Border Grid.Column="3" BorderBrush="{StaticResource NormalBorderBrush}" BorderThickness="0,0,1,0" Margin="0,-5,0,-3">
<TextBox Grid.Column="3" Text="{Binding Items[0].MarketShare, Mode=TwoWay, StringFormat=P2, Converter={StaticResource DecimalPercentageConverter}, ValidatesOnDataErrors=True}" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="60">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<i:InvokeCommandAction Command="{Binding Path=DataContext.SetMarketShareCommand, RelativeSource={RelativeSource AncestorType=UserControl}}" CommandParameter="{Binding Items[0]}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Border>
<ItemsPresenter Grid.Column="4"/>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource HoverOn}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource HoverOff}"/>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And the actual DataGrid:
<DataGrid ItemsSource="{Binding SeverityModificationFactorsGrouped}" AutoGenerateColumns="False" CanUserAddRows="False" MinRowHeight="25" Panel.ZIndex="0" AreRowDetailsFrozen="False">
<DataGrid.GroupStyle>
<GroupStyle ContainerStyle="{StaticResource SeverityModificationFactorGroupItemStyle}">
<GroupStyle.Panel>
<ItemsPanelTemplate>
<DataGridRowsPresenter/>
</ItemsPanelTemplate>
</GroupStyle.Panel>
</GroupStyle>
</DataGrid.GroupStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="{StaticResource AccumulationPerilHeader}" Binding="{Binding AccumulationPerilName}"/>
<DataGridTemplateColumn CellTemplate="{StaticResource ExposureGrowthReadonlyCellTemplate}">
...
</DataGrid>

Popup never loses focus

I'm having a problem with my popup. When the user clicks the profile, I want to display a popup.
This already works but the popup doesn't close when it loses focus.
I've tried to set the stayopen property to false but then the popup shows up for about half a second and then immediately closes.
I also tried to catch the focus lost event in code, but the event never triggers...
<UserControl
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:converters="clr-namespace:UserControlSolution.Converter"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
mc:Ignorable="d"
x:Class="UserControlSolution.ProfileControl"
x:Name="UserControl"
d:DesignWidth="640" d:DesignHeight="480"
Height="55">
<UserControl.Resources>
<converters:ConnectedStatusToColorConverter x:Key="ConnectedStatusToColorConverter"/>
<Style x:Key="ProfileOptionsStyle" TargetType="TextBlock">
<Setter Property="Padding" Value="7" />
<Setter Property="FontFamily" Value="Segoe UI" />
<Setter Property="Foreground" Value="Silver" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="TextAlignment" Value="Right" />
<Setter Property="Margin" Value="10,3,5,0" />
<Setter Property="FontSize" Value="14.5" />
<Setter Property="TextWrapping" Value="WrapWithOverflow" />
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource SelectGrey}" />
</Trigger>
</Style.Triggers>
</Style>
<Canvas x:Key="Lynx_logo_NoText" x:Name="Lynx_logo_NoText" HorizontalAlignment="Left" Height="189.333" UseLayoutRounding="False" VerticalAlignment="Top" Width="504.864">
<Canvas x:Name="Laag_2" Height="156.803" Canvas.Left="26.033" Canvas.Top="16.47" Width="450.509">
<Path Data="F1M140.0616,111.5394L140.0616,168.4354C140.0616,169.0754,139.9016,169.6314,139.5826,170.1064C139.2646,170.5874,138.7136,170.9654,137.9206,171.2384C137.1316,171.5194,136.0656,171.7644,134.7216,171.9584C133.3746,172.1524,131.7546,172.2564,129.8586,172.2564C127.8856,172.2564,126.2406,172.1524,124.9396,171.9584C123.6336,171.7644,122.5656,171.5194,121.7336,171.2384C120.9056,170.9654,120.3296,170.5874,120.0126,170.1064C119.6986,169.6314,119.5416,169.0754,119.5416,168.4354L119.5416,111.5394L93.9836,56.1284C93.1016,54.3004,92.5696,52.8684,92.3686,51.8324C92.1686,50.8104,92.3686,50.0044,92.9656,49.4514C93.5616,48.8954,94.6346,48.5374,96.1866,48.3784C97.7356,48.2214,99.8216,48.1414,102.4466,48.1414C104.8326,48.1414,106.7586,48.2214,108.2336,48.3784C109.7056,48.5374,110.8746,48.7554,111.7496,49.0294C112.6246,49.3174,113.2846,49.7144,113.7196,50.2254C114.1536,50.7424,114.5736,51.4014,114.9756,52.1934C114.9756,52.1934,128.1596,87.4004,130.2146,92.0934L130.4496,92.0934C132.2656,87.5664,134.1506,83.0514,136.0836,78.5604C138.0196,74.0694,139.9816,69.6334,141.9666,65.2574C141.9666,65.2574,164.0146,19.1754,164.4506,18.6164C164.8886,18.0634,165.4816,17.6464,166.2436,17.3654C166.9976,17.0844,168.0476,16.8684,169.4056,16.7064C170.7566,16.5504,172.4606,16.4704,174.5306,16.4704C177.3946,16.4704,179.6426,16.5734,181.2716,16.7684C182.8956,16.9674,184.0326,17.3474,184.6716,17.9014C185.3096,18.4604,185.5226,19.2544,185.3286,20.2884C185.1266,21.3194,184.5926,22.7164,183.7176,24.4624z" Fill="#FF646363" Height="155.786" Canvas.Left="66.261" Stretch="Fill" Canvas.Top="0" Width="93.104"/>
<Path Data="M468.9649,21.5218C470.5999,20.1588,471.8999,19.3438,472.8649,19.0808C473.8309,18.8198,474.5919,19.1598,475.1489,20.1048C475.7059,21.0488,476.0769,22.5998,476.2629,24.7498C476.4469,26.9018,476.5419,29.7638,476.5419,33.3308C476.5419,36.6918,476.4849,39.3148,476.3739,41.2048C476.2629,43.0938,476.0579,44.5898,475.7619,45.6918C475.4659,46.7938,475.1119,47.6358,474.7029,48.2108C474.2959,48.7898,473.7559,49.2888,473.0879,49.7068L415.7079,95.0558L473.0879,140.8758C473.7559,141.4028,474.3139,141.9788,474.7589,142.6088C475.2039,143.2388,475.5579,144.1038,475.8169,145.2058C476.0769,146.3088,476.2629,147.8048,476.3739,149.6938C476.4849,151.5828,476.5419,154.1028,476.5419,157.2518C476.5419,160.7158,476.4469,163.4478,476.2629,165.4398C476.0769,167.4358,475.7059,168.8258,475.1489,169.6128C474.5919,170.3998,473.8309,170.6638,472.8649,170.3998C471.8999,170.1388,470.5999,169.3248,468.9649,167.9588L402.6729,112.3758L338.6079,165.4398C336.9759,166.6998,335.6559,167.5138,334.6529,167.8808C333.6499,168.2508,332.8699,168.0138,332.3139,167.1718C331.7559,166.3328,331.4039,164.8648,331.2549,162.7628C331.1069,160.6648,331.0319,157.7788,331.0319,154.1028C331.0319,150.9538,331.0879,148.3828,331.1989,146.3868C331.3109,144.3948,331.4969,142.8198,331.7559,141.6638C332.0179,140.5098,332.3879,139.6708,332.8699,139.1438C333.3549,138.6208,333.8929,138.0418,334.4859,137.4128L388.4109,93.6378L334.4859,50.1798C333.8929,49.6558,333.3549,49.1308,332.8699,48.6048C332.3879,48.0808,332.0179,47.3208,331.7559,46.3218C331.4969,45.3248,331.3109,43.9348,331.1989,42.1488C331.0879,40.3648,331.0319,37.9518,331.0319,34.9058C331.0319,31.6528,331.1259,29.0008,331.3109,26.9538C331.4969,24.9068,331.8509,23.4388,332.3689,22.5448C332.8899,21.6548,333.6499,21.3118,334.6529,21.5218C335.6559,21.7328,336.9759,22.4668,338.6079,23.7258L402.2269,76.6328L468.9649,21.5218z"
Height="158.784" Canvas.Left="301.359" StrokeStartLineCap="Flat" Stretch="Fill" StrokeEndLineCap="Flat" Stroke="{Binding mainViewModel.IsConnected, Converter={StaticResource ConnectedStatusToColorConverter}}" StrokeThickness="7.281" StrokeMiterLimit="4" StrokeLineJoin="Miter" Canvas.Top="-1.115" Width="152.791"/>
<Path Data="F1M106.0738,163.4183C106.0738,165.0103,105.9928,166.3413,105.8348,167.4143C105.6748,168.4873,105.4178,169.4023,105.0598,170.1573C104.7018,170.9143,104.2638,171.4703,103.7478,171.8273C103.2298,172.1863,102.6138,172.3643,101.8988,172.3643L33.6678,172.3643C31.8368,172.3643,30.1078,171.7493,28.4788,170.5163C26.8478,169.2833,26.0328,167.1153,26.0328,164.0153L26.0328,21.1113C26.0328,20.4753,26.1918,19.9183,26.5098,19.4413C26.8268,18.9633,27.3848,18.5873,28.1798,18.3083C28.9738,18.0303,30.0478,17.7913,31.4008,17.5923C32.7528,17.3943,34.3828,17.2933,36.2918,17.2933C38.2788,17.2933,39.9298,17.3943,41.2418,17.5923C42.5538,17.7913,43.6078,18.0303,44.4028,18.3083C45.1968,18.5873,45.7548,18.9633,46.0728,19.4413C46.3898,19.9183,46.5508,20.4753,46.5508,21.1113L46.5508,154.5913L101.8988,154.5913C102.6138,154.5913,103.2298,154.7703,103.7478,155.1283C104.2638,155.4853,104.7018,156.0043,105.0598,156.6793C105.4178,157.3543,105.6748,158.2493,105.8348,159.3623C105.9928,160.4773,106.0738,161.8283,106.0738,163.4183" Fill="#FF646363" Height="155.071" Canvas.Left="0" Stretch="Fill" Canvas.Top="0.823" Width="80.041"/>
<Path Data="F1M312.2998,164.0872C312.2998,165.6792,312.0318,167.0302,311.4988,168.1442C310.9638,169.2582,310.2648,170.1712,309.4018,170.8872C308.5378,171.6032,307.5708,172.1202,306.5028,172.4382C305.4328,172.7542,304.3638,172.9142,303.2938,172.9142L296.5108,172.9142C294.3698,172.9142,292.4988,172.6942,290.8958,172.2592C289.2918,171.8222,287.7708,171.0262,286.3308,169.8732C284.8938,168.7212,283.4518,167.1502,282.0128,165.1612C280.5748,163.1742,279.0458,160.6282,277.4328,157.5262L230.3438,69.7332C227.8818,65.2002,225.4018,60.4492,222.8998,55.4782C220.3988,50.5092,218.0728,45.6782,215.9178,40.9852L215.6798,40.9852C215.8378,46.7112,215.9568,52.5562,216.0378,58.5202C216.1158,64.4842,216.1568,70.4092,216.1568,76.2932L216.1568,169.4552C216.1568,170.0132,215.9888,170.5492,215.6538,171.0662C215.3178,171.5842,214.7518,171.9812,213.9538,172.2592C213.1558,172.5382,212.1088,172.7752,210.8078,172.9752C209.5068,173.1722,207.8478,173.2732,205.8348,173.2732C203.8198,173.2732,202.1628,173.1722,200.8618,172.9752C199.5608,172.7752,198.5338,172.5382,197.7788,172.2592C197.0228,171.9812,196.4788,171.5842,196.1428,171.0662C195.8068,170.5492,195.6398,170.0132,195.6398,169.4552L195.6398,27.0292C195.6398,23.8492,196.5418,21.5832,198.3478,20.2302C200.1538,18.8792,202.1238,18.2022,204.2578,18.2022L214.3548,18.2022C216.7328,18.2022,218.7228,18.4012,220.3238,18.7982C221.9248,19.1972,223.3618,19.8532,224.6328,20.7662C225.9038,21.6822,227.1368,22.9552,228.3278,24.5842C229.5168,26.2142,230.7648,28.2632,232.0738,30.7272L268.2728,98.4812C270.5028,102.6162,272.6538,106.6512,274.7298,110.5882C276.8038,114.5242,278.8018,118.4012,280.7238,122.2192C282.6458,126.0352,284.5478,129.7932,286.4308,133.4912C288.3138,137.1892,290.1768,140.9072,292.0228,144.6442L292.1418,144.6442C291.9818,138.3632,291.8818,131.8202,291.8428,125.0222C291.8018,118.2232,291.7838,111.6822,291.7838,105.3992L291.7838,21.6612C291.7838,21.1062,291.9518,20.5882,292.2858,20.1102C292.6218,19.6332,293.1868,19.2162,293.9858,18.8582C294.7818,18.5002,295.8308,18.2432,297.1318,18.0832C298.4328,17.9242,300.1318,17.8442,302.2298,17.8442C304.0748,17.8442,305.6708,17.9242,307.0128,18.0832C308.3548,18.2432,309.4038,18.5002,310.1608,18.8582C310.9148,19.2162,311.4618,19.6332,311.7978,20.1102C312.1318,20.5882,312.2998,21.1062,312.2998,21.6612z"
Fill="#FF646363" Height="155.429" Canvas.Left="169.607" Stretch="Fill" Canvas.Top="1.374" Width="116.66"/>
</Canvas>
<Canvas x:Name="Laag_3"/>
</Canvas>
</UserControl.Resources>
<Grid x:Name="HeaderContainer" Grid.Row="0" Background="{StaticResource VeryDarkGrey}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ProfilePanelStates">
<VisualState x:Name="ProfilePanelMouseEnter">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="ProfilePanel">
<EasingColorKeyFrame KeyTime="0" Value="#FF404040"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ProfilePanelMouseOut"/>
<VisualState x:Name="ProfilePanelMouseDown">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="ProfilePanel">
<EasingColorKeyFrame KeyTime="0" Value="#FF404040"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontSize)" Storyboard.TargetName="UserNameTextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="17.666"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="ProfilePicture">
<EasingDoubleKeyFrame KeyTime="0" Value="43"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ProfilePicture">
<EasingDoubleKeyFrame KeyTime="0" Value="43"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="ProfilePanelMouseUp">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="ProfilePanel">
<EasingColorKeyFrame KeyTime="0" Value="#FF404040"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(TextElement.FontSize)" Storyboard.TargetName="UserNameTextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="18.667"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Width)" Storyboard.TargetName="ProfilePicture">
<EasingDoubleKeyFrame KeyTime="0" Value="45"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="ProfilePicture">
<EasingDoubleKeyFrame KeyTime="0" Value="45"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox x:Name="LynxLogoContainer" StretchDirection="DownOnly" Stretch="Uniform" Height="35" Grid.Column="0" HorizontalAlignment="Left" Margin="15,0,0,0" >
<ContentControl x:Name="MessageAction" Content="{StaticResource Lynx_logo_NoText}" Margin="0,5" />
</Viewbox>
<Grid x:Name="ProfilePanel" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Background="Transparent" MouseLeftButtonDown="ProfilePanel_MouseLeftButtonDown">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<ei:GoToStateAction StateName="ProfilePanelMouseDown"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeftButtonUp">
<ei:GoToStateAction StateName="ProfilePanelMouseUp"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseEnter">
<ei:GoToStateAction StateName="ProfilePanelMouseEnter"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseLeave">
<ei:GoToStateAction StateName="ProfilePanelMouseOut"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="UserNameTextBlock" Grid.Column="0" TextWrapping="WrapWithOverflow" Foreground="Silver"
TextAlignment="Right" FontSize="18.667" HorizontalAlignment="Right"
TextTrimming="CharacterEllipsis" FontFamily="Segoe UI Light" Text="Laurens" />
<WrapPanel x:Name="ProfilePictureContainer" Grid.Column="1" Width="45" Height="45" HorizontalAlignment="Right">
<Image x:Name="ProfilePicture" Source="/Image/JV.jpg" Width="45" Height="45" />
</WrapPanel>
</Grid>
<Popup x:Name="ProfilePopup" Placement="Bottom" PlacementTarget="{Binding ElementName=ProfilePictureContainer}" Height="Auto" Width="Auto"
MinWidth="{Binding ActualWidth, ElementName=ProfilePanel}" MaxWidth="{Binding ActualWidth, ElementName=HeaderContainer}"
VerticalOffset="2" PopupAnimation="Slide" AllowsTransparency="True">
<Border Background="{StaticResource VeryDarkGrey}" BorderThickness="0,2,0,0" BorderBrush="#3C3C3C">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Vertical" VerticalAlignment="Top" Margin="0,0,0,5">
<TextBlock Style="{StaticResource ProfileOptionsStyle}" Text="Status: Online" />
<TextBlock Style="{StaticResource ProfileOptionsStyle}" Text="Verander profielfoto" />
</StackPanel>
<StackPanel Grid.Row="1" Margin="0,0,0,3">
<Rectangle HorizontalAlignment="Stretch" Fill="#FF4E4E4E" Height="1" Margin="10,0"/>
<TextBlock Style="{StaticResource ProfileOptionsStyle}" Text="Afsluiten" Margin="5,2,5,0"/>
</StackPanel>
</Grid>
</Border>
</Popup>
</Grid>
This is the code where I open the popup
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace UserControlSolution
{
/// <summary>
/// Interaction logic for ProfileControl.xaml
/// </summary>
public partial class ProfileControl : UserControl
{
public ProfileControl()
{
this.InitializeComponent();
this.ProfilePopup.LostFocus += new RoutedEventHandler(ProfilePopup_LostFocus);
}
void ProfilePopup_LostFocus(object sender, RoutedEventArgs e)
{
ProfilePopup.IsOpen = false;
}
private void ProfilePanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ProfilePopup.IsOpen = true;
}
}
}
I would handle this by setting the StaysOpen property to false and Binding the Popup.IsOpen property to a bool property and setting the property to false when I need the Popup to close. The problem of trying to do this in the LostFocus event is that the Popup will lose focus even if the user just clicks on a control inside the Popup, as that control will take the focus... I'm guessing that is why your Popup was closing so quickly.
For example, I have a custom AutoCompleteTextBox and that closes the Popup control in various event handlers after a user have selected one of the suggestions:
private void ListBox_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
Text = SelectedSuggestion;
if (SuggestionSelected != null) SuggestionSelected(this, new EventArgs());
Focus();
CaretIndex = Text.Length;
IsPopupOpen = false; // <<< Here is the line that closes the Popup
}

Categories

Resources