C# 如果文本超出文本框的可用宽度,则显示工具提示
当文本框中的文本超过文本框的可用大小时,我试图显示工具提示,我已编写了一个附加属性,但如果我在文本框上设置了显式宽度,则该属性可以工作,但在重新调整窗口大小时,该属性不起作用(当我重新调整窗口大小时,文本框的大小会减小) 我的XAML:C# 如果文本超出文本框的可用宽度,则显示工具提示,c#,wpf,xaml,C#,Wpf,Xaml,当文本框中的文本超过文本框的可用大小时,我试图显示工具提示,我已编写了一个附加属性,但如果我在文本框上设置了显式宽度,则该属性可以工作,但在重新调整窗口大小时,该属性不起作用(当我重新调整窗口大小时,文本框的大小会减小) 我的XAML: <Window.Resources> <Style TargetType="TextBox"> <Setter Property="local:TextBoxCropBehavior.TextBoxTool
<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="local:TextBoxCropBehavior.TextBoxToolTip" Value="True"/>
<Setter Property="BorderBrush" Value="Green"/>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Text=" first Textbox with long text dfdsfdsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsfsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsf" x:Name="x" HorizontalAlignment="Right"/>
<TextBox Text="Seceond text box" x:Name="y" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
我的附属财产:
public static class TextBoxCropBehavior
{
public static bool GetTextBoxToolTip(DependencyObject obj)
{
return (bool)obj.GetValue(TextBoxCropToolTipProperty);
}
public static void SetTextBoxToolTip(DependencyObject obj, bool value)
{
obj.SetValue(TextBoxCropToolTipProperty, value);
}
public static readonly DependencyProperty TextBoxCropToolTipProperty = DependencyProperty.RegisterAttached("TextBoxToolTip", typeof(bool), typeof(TextBoxCropBehavior), new UIPropertyMetadata(false, OnTextCropChanges));
private static void OnTextCropChanges(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var textbox = d as TextBox;
textbox.SizeChanged += textbox_SizeChanged;
}
static void textbox_SizeChanged(object sender, SizeChangedEventArgs e)
{
var textbox = sender as TextBox;
textbox.Measure(new Size(Double.MaxValue, Double.MaxValue));
var width = textbox.DesiredSize.Width;
if (textbox.ActualWidth < width)
{
ToolTipService.SetToolTip(textbox, textbox.Text);
}
else
{
ToolTipService.SetToolTip(textbox, null);
}
}
}
公共静态类TextBoxCropBehavior
{
公共静态bool GetTextBoxToolTip(DependencyObject obj)
{
返回(bool)对象获取值(textBoxCroptolTipProperty);
}
公共静态void SetTextBoxToolTip(DependencyObject对象,布尔值)
{
对象设置值(TextBoxCroptolTipProperty,值);
}
public static readonly dependencProperty textboxcroptoltipproperty=dependencProperty.RegisterAttached(“TextBoxToolTip”、typeof(bool)、typeof(TextBoxCropBehavior)、new UIPropertyMetadata(false、OnTextCropChanges));
私有静态void OnTextCropChanges(DependencyObject d、DependencyPropertyChangedEventArgs e)
{
var textbox=d作为textbox;
textbox.SizeChanged+=textbox\u SizeChanged;
}
静态无效文本框\u SizeChanged(对象发送方,SizeChangedEventArgs e)
{
var textbox=发送方作为textbox;
textbox.Measure(新大小(Double.MaxValue,Double.MaxValue));
var width=textbox.DesiredSize.width;
if(textbox.ActualWidth
谁能告诉我哪里做错了吗?我不知道您是否必须使用附加属性。但是试试这个 我修改了文本框的默认样式
转换器
public类ToolTipConverter:IMultiValueConverter
{
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
如果(values==null | | values.Count()<2 | | values[0]==null){return null;}
如果((双)值[0]>0){返回值[1];}
else{return null;}
}
公共对象[]转换回(对象值,类型[]目标类型,对象参数,CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
编辑:行为版本
行为
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
}
公共类OptionalToolTipBehavior:行为
{
受保护的覆盖无效附加()
{
this.AssociatedObject.Loaded+=AssociatedObject\u Loaded;
base.onatached();
}
已加载无效关联对象(对象发送方,事件参数e)
{
this.AssociatedObject.Loaded-=AssociatedObject\u Loaded;
ScrollViewer ScrollViewer=this.FindScrollViewer(关联对象);
如果(scrollViewer!=null)
{
this.AssociatedObject.SetBinding(TextBox.ToolTipProperty,
新绑定(){Source=scrollViewer,
路径=新属性路径(ScrollViewer.ScrollableWidthProperty),
Converter=ScrollableWithToTooltipConverter.Instance,
ConverterParameter=this.AssociatedObject.Text});
}
}
私有ScrollViewer FindScrollViewer(DependencyObject元素)
{
if(元素为ScrollViewer){返回元素为ScrollViewer;}
int childCount=VisualTreeHelper.GetChildrenCount(元素);
for(int i=0;i0)
{
返回参数.ToString();
}
返回null;
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
}
最好的方法是总是有工具提示,而不是在上面做任何逻辑。您只需要将ToolTip属性应用于文本框X。我希望它具有样式,以便其他开发人员可以自动获得该属性。@XAMLLover我尝试了相同的方法,但由于某些原因,它不起作用,仅当文本框具有显式的say Width=“300”时才起作用。我使用SizeChanged事件修复了该问题。谢谢大家的帮助。是的,我试过这种方法,但我觉得使用附加的行为更容易。谢谢你分享你的想法。我很高兴你解决了这个问题。我想告诉您,可以使用VisualTreeHelper将此代码更改为附加行为:)
<Window.Resources>
<study:ToolTipConverter x:Key="ToolTipConverter"/>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="True">
<Themes:ListBoxChrome.ToolTip>
<MultiBinding Converter="{StaticResource ToolTipConverter}">
<Binding ElementName="PART_ContentHost" Path="ScrollableWidth"/>
<Binding RelativeSource="{RelativeSource AncestorType={x:Type TextBox}}" Path="Text"/>
</MultiBinding>
</Themes:ListBoxChrome.ToolTip>
<ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Themes:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Text=" first Textbox with long text dfdsfdsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsfsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsf" HorizontalAlignment="Right"/>
<TextBox Text="Seceond text box" Grid.Row="2" HorizontalAlignment="Right"/>
</Grid>
public class ToolTipConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null || values.Count() < 2 || values[0] == null) { return null; }
if ((double)values[0] > 0) { return values[1]; }
else { return null; }
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
<TextBox Text=" first Textbox with long text dfdsfdsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsfsfdsfdslkjfwlekjorifdsfmldskfwepisdmfds;fdsf" HorizontalAlignment="Right" x:Name="PART_Textbox">
<i:Interaction.Behaviors>
<study:OptionalToolTipBehavior/>
</i:Interaction.Behaviors>
</TextBox>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
public class OptionalToolTipBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
this.AssociatedObject.Loaded += AssociatedObject_Loaded;
base.OnAttached();
}
void AssociatedObject_Loaded(object sender, EventArgs e)
{
this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
ScrollViewer scrollViewer = this.FindScrollViewer(AssociatedObject);
if (scrollViewer != null)
{
this.AssociatedObject.SetBinding(TextBox.ToolTipProperty,
new Binding() { Source = scrollViewer,
Path = new PropertyPath(ScrollViewer.ScrollableWidthProperty),
Converter = ScrollableWithToTooltipConverter.Instance,
ConverterParameter=this.AssociatedObject.Text});
}
}
private ScrollViewer FindScrollViewer(DependencyObject element)
{
if (element is ScrollViewer) { return element as ScrollViewer; }
int childCount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childCount; i++)
{
return this.FindScrollViewer(VisualTreeHelper.GetChild(element, i));
}
return null;
}
private class ScrollableWithToTooltipConverter : IValueConverter
{
public static readonly ScrollableWithToTooltipConverter Instance = new ScrollableWithToTooltipConverter();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if((double) value > 0)
{
return parameter.ToString();
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}