如何在文本框中显示气球提示?

我有一个使用XAML和MVVM的C#WPF应用程序。 我的问题是:如何在文本框上方显示用户输入的某些无效数据的气球工具提示?

我想使用Microsoft的本机气球控件 。 我如何将其实现到我的应用程序中?

我一直在寻找比BalloonDecorator更好的解决方案,并且遇到了http://www.hardcodet.net/projects/wpf-notifyicon项目。 它使用的是最低级别的WinAPI,这可能会让您在构建自己的解决方案方面领先一步。 看起来乍一看它可以解决它,但我没有足够的时间来validationBalloonTip是否可以像你所描述的那样表现出来。

祝你的项目好运!

只需添加对System.Windows.FormsC:\ Program Files \ Reference Assemblies \ Microsoft \ Framework.NETFramework \ v4.0 \ WindowsFormsIntegration.dll的引用 ,然后:

WindowsFormsHost host =new WindowsFormsHost(); var toolTip1 = new System.Windows.Forms.ToolTip(); toolTip1.AutoPopDelay = 5000; toolTip1.InitialDelay = 1000; toolTip1.ReshowDelay = 500; toolTip1.ShowAlways = true; toolTip1.IsBalloon = true; toolTip1.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info; toolTip1.ToolTipTitle = "Title:"; System.Windows.Forms.TextBox tb = new System.Windows.Forms.TextBox(); tb.Text="Go!"; toolTip1.SetToolTip(tb, "My Info!"); host.Child = tb; grid1.Children.Add(host); //a container for windowsForm textBox 

这是WPF中WinForm ToolTip Ballon的示例:

在此处输入图像描述

希望这有帮助!

这个BalloonDecorator项目是我在当前项目中使用的项目,用于显示帮助提示和错误通知。 我知道您可以修改您的错误模板以显示此装饰器,就像您可以显示图标而不是红色边框一样。 使用装饰器的好处是你可以使它看起来像你想要的,并且不必依赖WinForms。

BalloonDecorator.cs

 using System; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace MyNamespace { public class BalloonDecorator : Decorator { private static double _thickness = 0; private static int OpeningGap = 10; public static readonly DependencyProperty BackgroundProperty = DependencyProperty.Register("Background", typeof (Brush), typeof (BalloonDecorator)); public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.Register("BorderBrush", typeof (Brush), typeof (BalloonDecorator)); public static readonly DependencyProperty PointerLengthProperty = DependencyProperty.Register("PointerLength", typeof (double), typeof (BalloonDecorator), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure)); public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof (double), typeof (BalloonDecorator), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure)); public Brush Background { get { return (Brush) GetValue(BackgroundProperty); } set { SetValue(BackgroundProperty, value); } } public Brush BorderBrush { get { return (Brush) GetValue(BorderBrushProperty); } set { SetValue(BorderBrushProperty, value); } } public double PointerLength { get { return (double) GetValue(PointerLengthProperty); } set { SetValue(PointerLengthProperty, value); } } public double CornerRadius { get { return (double) GetValue(CornerRadiusProperty); } set { SetValue(CornerRadiusProperty, value); } } protected override Size ArrangeOverride(Size arrangeSize) { UIElement child = Child; if (child != null) { double pLength = PointerLength; Rect innerRect = Rect.Inflate(new Rect(pLength, 0, Math.Max(0, arrangeSize.Width - pLength), arrangeSize.Height), -1 * _thickness, -1 * _thickness); child.Arrange(innerRect); } return arrangeSize; } protected override Size MeasureOverride(Size constraint) { UIElement child = Child; Size size = new Size(); if (child != null) { Size innerSize = new Size(Math.Max(0, constraint.Width - PointerLength), constraint.Height); child.Measure(innerSize); size.Width += child.DesiredSize.Width; size.Height += child.DesiredSize.Height; } Size borderSize = new Size(2 * _thickness, 2 * _thickness); size.Width += borderSize.Width + PointerLength; size.Height += borderSize.Height; return size; } protected override void OnRender(DrawingContext dc) { Rect rect = new Rect(0, 0, RenderSize.Width, RenderSize.Height); dc.PushClip(new RectangleGeometry(rect)); dc.DrawGeometry(Background, new Pen(BorderBrush, _thickness), CreateBalloonGeometry(rect)); dc.Pop(); } private StreamGeometry CreateBalloonGeometry(Rect rect) { double radius = Math.Min(CornerRadius, rect.Height / 2); double pointerLength = PointerLength; // All the points on the path Point[] points = { new Point(pointerLength + radius, 0), new Point(rect.Width - radius, 0), // Top new Point(rect.Width, radius), new Point(rect.Width, rect.Height - radius), // Right new Point(rect.Width - radius, rect.Height), // Bottom new Point(pointerLength + radius, rect.Height), // Bottom new Point(pointerLength, rect.Height - radius), // Left new Point(pointerLength, radius) // Left }; StreamGeometry geometry = new StreamGeometry(); geometry.FillRule = FillRule.Nonzero; using (StreamGeometryContext ctx = geometry.Open()) { ctx.BeginFigure(points[0], true, true); ctx.LineTo(points[1], true, false); ctx.ArcTo(points[2], new Size(radius, radius), 0, false, SweepDirection.Clockwise, true, false); ctx.LineTo(points[3], true, false); ctx.ArcTo(points[4], new Size(radius, radius), 0, false, SweepDirection.Clockwise, true, false); ctx.LineTo(points[5], true, false); ctx.ArcTo(points[6], new Size(radius, radius), 0, false, SweepDirection.Clockwise, true, false); // Pointer if (pointerLength > 0) { ctx.LineTo(rect.BottomLeft, true, false); ctx.LineTo(new Point(pointerLength, rect.Height - radius - OpeningGap), true, false); } ctx.LineTo(points[7], true, false); ctx.ArcTo(points[0], new Size(radius, radius), 0, false, SweepDirection.Clockwise, true, false); } return geometry; } } } 

只需确保将此类的命名空间加载到XAML导入中(我使用名为“Framework”的命名空间),并且使用起来很简单:

         

显然,我将可见性绑定到绑定,但您可以将其设置为true并将其放在Validation.ErrorTemplate中。

希望这可以帮助!

也许您可以使用WindowsFormsHost类型在WPF中托管Windows窗体控件。

MSDN上有关于如何执行此操作的演练:

在WPF中承载Windows窗体复合控件

使用此技术,您可以使用System.Windows.Forms.ToolTip控件。 如果将此控件的IsBalloon属性设置为true,它将显示为气球窗口。