je suis allé de l'avant et créé un site CodePlex pour ce qui inclut « Toast popups » et de contrôle « Ballons d'aide ». Ces versions ont plus de fonctionnalités que ce qui est décrit ci-dessous. Code Plex Project.
Voici le lien vers le Nuget Package
Voici ma solution pour la légende du ballon. Certaines des choses que je voulais qu'il fasse différemment:
- fondu lorsque la souris entre. Fondu lorsque la souris quitte et ferme la fenêtre lorsque l'opacité atteint 0.
- Si la souris est au-dessus de la fenêtre, l'opacité sera à 100% et ne se fermera pas.
- La hauteur de la fenêtre de ballon est dynamique.
- Utiliser les déclencheurs d'événements au lieu de minuteries.
- Placez le ballon sur le côté gauche ou à droite du contrôle.
Voici les images d'aide que j'ai utilisé.
J'ai créé un UserControl avec une simple icône "Aide".
<UserControl x:Class="Foundation.FundRaising.DataRequest.Windows.Controls.HelpBalloon"
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"
Name="HelpBalloonControl"
d:DesignHeight="20" d:DesignWidth="20" Background="Transparent">
<Image Width="20" Height="20"
MouseEnter="ImageMouseEnter"
Cursor="Hand"
IsManipulationEnabled="True"
Source="/Foundation.FundRaising.DataRequest.Windows;component/Resources/help20.png" />
Et a ajouté à son code derrière.
public partial class HelpBalloon : UserControl
{
private Balloon balloon = null;
public HelpBalloon()
{
InitializeComponent();
}
public string Caption { get; set; }
public Balloon.Position Position { get; set; }
private void ImageMouseEnter(object sender, MouseEventArgs e)
{
if (balloon == null)
{
balloon = new Balloon(this, this.Caption);
balloon.Closed += BalloonClosed;
balloon.Show();
}
}
private void BalloonClosed(object sender, EventArgs e)
{
this.balloon = null;
}
}
Voici le code XAML de la fenêtre Balloon que le contrôle UserControl ouvre.
<Window x:Class="Foundation.FundRaising.DataRequest.Windows.Balloon"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="90" Width="250" WindowStyle="None"
ResizeMode="NoResize" ShowInTaskbar="False"
Topmost="True" IsTabStop="False"
OverridesDefaultStyle="False"
SizeToContent="Height"
AllowsTransparency="True"
Background="Transparent" >
<Grid RenderTransformOrigin="0,1" >
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="Path">
<Setter Property="Fill" Value="#fdfdfd"/>
<Setter Property="Stretch" Value="Fill"/>
<Setter Property="Width" Value="22"/>
<Setter Property="Height" Value="31"/>
<Setter Property="Panel.ZIndex" Value="99"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect Color="#FF757575" Opacity=".7"/>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<Path
HorizontalAlignment="Left"
Margin="15,3,0,0"
Data="M10402.99154,55.5381L10.9919,0.64 0.7,54.9"
x:Name="PathPointLeft"/>
<Path
HorizontalAlignment="Right"
Margin="175,3,0,0"
Data="M10402.992,55.5381 L10284.783,3.2963597 0.7,54.9"
x:Name="PathPointRight">
</Path>
</StackPanel>
<Border Margin="5,-3,5,5"
CornerRadius="7" Panel.ZIndex="100"
VerticalAlignment="Top">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
<LinearGradientBrush.RelativeTransform>
<RotateTransform Angle="90" CenterX="0.7" CenterY="0.7" />
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="#FFFDFDFD" Offset=".2"/>
<GradientStop Color="#FFB6FB88" Offset=".8"/>
</LinearGradientBrush>
</Border.Background>
<Border.Effect>
<DropShadowEffect Color="#FF757575" Opacity=".7"/>
</Border.Effect>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Width="35"
Margin="5"
VerticalAlignment="Top" Height="35"
Source="Resources/help.png" />
<TextBlock Grid.Column="1"
TextWrapping="Wrap"
Margin="0,10,10,10"
TextOptions.TextFormattingMode="Display"
x:Name="textBlockCaption"
Text="This is the caption"/>
</Grid>
</Border>
</StackPanel>
<!-- Animation -->
<Grid.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard x:Name="StoryboardLoad">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="0.0" To="1.0" Duration="0:0:2" />
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:3" BeginTime="0:0:3" Completed="DoubleAnimationCompleted"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<RemoveStoryboard BeginStoryboardName="StoryboardLoad"/>
<RemoveStoryboard BeginStoryboardName="StoryboardFade"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard x:Name="StoryboardFade">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(UIElement.Opacity)" From="1.0" To="0.0" Duration="0:0:2" BeginTime="0:0:1" Completed="DoubleAnimationCompleted"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<Grid.RenderTransform>
<ScaleTransform ScaleY="1" />
</Grid.RenderTransform>
</Grid>
Et le code derrière la fenêtre ballon.
public partial class Balloon : Window
{
public enum Position
{
Left,
Right
}
public Balloon(Control control, string caption, Position position)
{
InitializeComponent();
this.textBlockCaption.Text = caption;
// Compensate for the bubble point
double captionPointMargin = this.PathPointLeft.Margin.Left;
Point location = GetControlPosition(control);
if (position == Position.Left)
{
this.PathPointRight.Visibility = Visibility.Hidden;
this.Left = location.X + (control.ActualWidth/2) - captionPointMargin;
}
else
{
this.PathPointLeft.Visibility = Visibility.Hidden;
this.Left = location.X - this.Width + control.ActualWidth + (captionPointMargin/2);
}
this.Top = location.Y + (control.ActualHeight/2);
}
private static Point GetControlPosition(Control control)
{
Point locationToScreen = control.PointToScreen(new Point(0, 0));
var source = PresentationSource.FromVisual(control);
return source.CompositionTarget.TransformFromDevice.Transform(locationToScreen);
}
private void DoubleAnimationCompleted(object sender, EventArgs e)
{
if (!this.IsMouseOver)
{
this.Close();
}
}
}
J'ai déjà donné une réponse dans le lien suivant. S'il vous plaît suivez-le. [Comment Créer ballon pour Caps avertissement Lock] [1] [1]: http://stackoverflow.com/questions/1092808/wpf-warn-about-capslock/8060520#8060520 –