当前位置: 首页 > 编程语言 > C#

裁剪文本时显示ToolTip分享

时间:2023-04-10 14:42:01 C#

裁剪文本时显示ToolTip如何只在裁剪文本时显示ToolTip?像windowsdesktp快捷方式图标。在Eyjafj上工作...无论如何,我找到了一个有效的、主要是声明性的解决方案,至少不需要自定义控件。要克服的第一个障碍是进入TextBlock。因为ToolTip在可视化树之外呈现,所以您不能使用RelativeSource绑定或ElementName来获取TextBlock。幸运的是,ToolTip类通过PlacementTarget属性提供了对其关联元素的引用。因此,您可以将ToolTip的Visibility属性绑定到ToolTip本身,并使用其PlacementTarget属性来访问TextBlock的属性:下一步是使用转换器来查看我们必须确定的TextBlock是否应该可见。您可以使用ActualWidth和DesiredSize来做到这一点。ActualWidth正是它听起来的样子;TextBlock在屏幕上呈现的宽度。DesiredSize是TextBlock的首选宽度。唯一的问题是DesiredSize似乎考虑了TextTrimming并且没有为您提供完整的未修剪文本的宽度。要解决此问题,我们可以通过Double.Positiveinfinity重新调用Measure方法,如果它不受约束,它实际上会向TextBlock询问宽度。这会更新DesiredSize属性,然后我们可以比较它:textBlock.Measure(newSize(Double.PositiveInfinity,Double.PositiveInfinity));if(((FrameworkElement)value).ActualWidth如果您希望此方法自动应用于TextBlocks,或者不想将资源浪费在创建始终不可见的工具提示上,则此方法实际上在这里声明为附加行为。以下是我的示例的完整代码:Converter:publicclassTrimmedTextBlockVisibilityConverter:IValueConverter{publicobjectConvert(objectvalue,TypetargetType,objectparameter,System.Globalization.CultureInfoculture){if(value==null)returnVisibility.Collapsed;FrameworkElementtextBlock=(FrameworkElement)value;textBlock.Measure(newSystem.Windows.Size(Double.PositiveInfinity,Double.PositiveInfinity));if(((FrameworkElement)value).ActualWidthXAML:....我找到了最简单的解决方案来扩展TextBlock并比较文本长度以确定是否显示工具提示,即publicclassToolTipTextBlock:TextBlock{protectedoverridevoidOnToolTipOpening(ToolTipEventArgse){if(TextTrimming!=TextTrimming.None){e.Handled=!IsTextTrimmed();}}privateboolIsTextTrimmed(){vartypeface=newTypeface(FontFamily,FontStyle,FontWeight,FontStretch);varformattedText=newFormattedText(Text,CultureInfo.CurrentCulture,FlowDirection,typeface,FontSize,Foreground);返回formattedText.Width>Act宽度;然后像这样在你的xaml中使用这个自定义文本块:基于这个页面上的想法和另一个答案的额外算法更正,我使这个非常便携的类非常容易使用它的目的是启用修剪和显示修剪文本时TextBlock上的工具提示,正如许多应用程序所了解的那样。事实证明,修剪检测在我的应用程序中是准确的。工具提示将在显示修剪椭圆时准确显示。XAML使用法C#使用法vartextBlock=newTextBlock{Text="Demo"};TextBlockAutoToolTip.SetEnabled(textBlock,true);使用系统完成整个课程;使用System.Globalization;使用System.Windows;使用System.Windows.Controls;使用System.Windows.Data;使用System.Windows.Media;namespaceUnclassified.UI{//////修剪文本时在TextBlock上显示工具提示。///publicclassTextBlockAutoToolTip{//////Enabled附加属性。///publicstaticreadonlyDependencyPropertyEnabledProperty=DependencyProperty.RegisterAttached("Enabled",typeof(bool),typeof(TextBlockAutoToolTip),newFrameworkPropertyMetadata(newPropertyChangedCallback(OnAutoToolTipEnabledChanged)));//////在TextBlock控件上设置Enabled附加属性。//////文本块控件。///价值。publicstaticvoidSetEnabled(DependencyObjectdependencyObject,boolenabled){dependencyObject.SetValue(EnabledProperty,enabled);}私人的staticreadonlyTrimmedTextBlockVisibilityConverterttbvc=newTrimmedTextBlockVisibilityConverter();privatestaticvoidOnAutoToolTipEnabledChanged(DependencyObjectdependencyObject,DependencyPropertyChangedEventArgsargs){TextBlocktextBlock=dependencyObjectasTextBlock;if(textBlock!=null){boolenabled=(bool)args.NewValue;if(enabled){vartoolTip=newToolTip{Placement=System.Windows.Controls.Primitives.PlacementMode.Relative,VerticalOffset=-3,Horizo??ntalOffset=-5,Padding=newThickness(4,2,4,2),背景=Brushes.White};toolTip.SetBinding(UIElement.VisibilityProperty,newSystem.Windows.Data.Binding{RelativeSource=newSystem.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),Path=newPropertyPath("PlacementTarget"),转换器=ttbvc});toolTip.SetBinding(ContentControl.ContentProperty,newSystem.Windows.Data.Binding{RelativeSource=newSystem.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),Path=newPropertyPath("PlacementTarget.Text")});toolTip.SetBinding(Control.ForegroundProperty,newSystem.Windows.Data.Binding{RelativeSource=newSystem.Windows.Data.RelativeSource(System.Windows.Data.RelativeSourceMode.Self),Path=newPropertyPath("PlacementTarget.Foreground")});textBlock.ToolTip=工具提示;textBlock.TextTrimming=TextTrimming.CharacterEllipsis;}}}privateclassTrimmedTextBlockVisibilityConverter:IValueConverter{//来源1:https://stackoverflow.com/a/21863054//来源2:https://stackoverflow.com/a/25436070publicobjectConvert(objectvalue,TypetargetType,objectparameter,CultureInfoculture){vartextBlock=valueasTextBlock;如果(textBlock==null)返回Visibility.Collapsed;字体typeface=newTypeface(textBlock.FontFamily,textBlock.FontStyle,textBlock.FontWeight,textBlock.FontStretch);//FormattedText用于测量整个宽度ofTextBlock容器FormattedTextformattedText=newFormattedText(textBlock.Text,System.Threading.Thread.CurrentThread.CurrentCulture,textBlock.FlowDirection,typeface,textBlock.FontSize,textBlock.Foreground);formattedText.MaxTextWidth=textBlock.ActualWidth;//当FormattedText实例的最大文本宽度设置为textBlock的//实际宽度时,如果正在修剪textBlock以适合//格式化文本将报告比textBlock更大的高度。无论//textBlock是单行还是多行,都应该起作用。//宽度检查检测是否有任何单行太长而无法容纳在文本区域内,//只有在没有空格的长文本跨度时才会发生这种情况。boolisTrimmed=formattedText.Height>textBlock.ActualHeight||格式化文本.MinWidth>格式化文本.MaxTextWidth;返回isTrimmed?Visibility.Visible:Visibility.Collapsed;}publicobjectConvertBack(对象值,输入targetType、对象参数、CultureInfo文化){thrownewNotImplementedException();}}}}行动就是爱,行动就是生命公共类TextBlockAutoToolTipBehavior:行为{privateToolTip_toolTip;protectedoverridevoidOnAttached(){base.OnAttached();_toolTip=newToolTip{Placement=PlacementMode.Relative,VerticalOffset=0,Horizo??ntalOffset=0};ToolTipService.SetShowDuration(_toolTip,int.MaxValue);_toolTip.SetBinding(ContentControl.ContentProperty,newBinding{Path=newPropertyPath("Text"),Source=AssociatedObject});AssociatedObject.TextTrimming=TextTrimming.CharacterEllipsis;AssociatedObject.AddValueChanged(TextBlock.TextProperty,TextBlockOnTextChanged);AssociatedObject.SizeChanged+=AssociatedObjectOnSizeChanged;}protectedoverridevoidOnDetaching(){base.OnDetaching();AssociatedObject.RemoveValueChanged(TextBlock.TextProperty,TextBlockOnTextChanged);AssociatedObject.SizeChanged-=AssociatedObjectOnSizeChanged;}privatevoidAssociatedObjectOnSizeChanged(objectsender,SizeChangedEventArgssizeChangedEventArgs){检查工具提示可见性();}privatevoidTextBlockOnTextChanged(objectsender,EventArgseventArgs){CheckToolTipVisibility();}privatevoidCheckToolTipVisibility(){if(AssociatedObject.ActualWidth==0)Dispatcher.BeginInvoke(newAction(()=>AssociatedObject.ToolTip=CalculateIsTextTrimmed(AssociatedObject)?_toolTip:null),DispatcherPriority.Loaded);否则AssociatedObject.ToolTip=CalculateIsTextTrimmed(AssociatedObject)?_toolTip:空;}//来源:https://stackoverflow.com/questions/1041820/how-can-i-determine-if-my-textblock-text-is-being-trimmedprivatestaticboolCalculateIsTextTrimmed(TextBlocktextBlock){Typefacetypeface=新字体(textBlock.FontFamily,textBlock.FontStyle,textBlock.FontWeight,textBlock.FontStretch);//FormattedText用于测量TextBlock容器容纳的文本的整个宽度FormattedTextformattedText=newFormattedText(textBlock.Text,System.Threading.Thread.CurrentThread.CurrentCulture,textBlock.FlowDirection,字体,textBlock.FontSize,textBlock.Foreground){MaxTextWidth=textBlock.ActualWidth};//当FormattedText实例的最大文本宽度设置为textBlock的//实际宽度时,如果正在修剪textBlock以适合//格式化文本将报告比textBlock更大的高度。无论//textBlock是单行还是多行,都应该起作用。//宽度检查检测是否有任何单行太长而无法容纳在文本区域内,//只有在没有空格的长文本跨度时才会发生这种情况。返回(formattedText.Height>textBlock.ActualHeight||formattedText.MinWidth>formattedText.MaxTextWidth);}}使用方法:所需的扩展方法:publicstaticclassUITools{publicstaticvoidAddValueChanged(thisTobj,DependencyPropertyproperty,EventHandlerhandler)whereT:DependencyObject{vardesc=DependencyPropertyDescriptor.FromProperty(property,typeof(T));desc.AddValueC挂起(对象,处理程序);}publicstaticvoidRemoveValueChanged(thisTobj,DependencyPropertyproperty,EventHandlerhandler)whereT:DependencyObject{vardesc=DependencyPropertyDescriptor.FromProperty(property,typeof(T));desc.RemoveValueChanged(obj,handler);我认为您可以创建一个转换器,将文本块的ActualWidth与其DesiredSize.Width进行比较,并返回此处发布的带有附加属性的VisibilityAlternative答案,我认为这比使用转换器或派生的TextBlock控件好。以上是C#学习教程:裁剪文本时,显示tooltip,分享所有内容。如果对大家有用,需要进一步了解C#学习教程,希望大家多加关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: