我在我的C#应用程序中使用WPF,其中我有几个文本不适合的标签。我想要的是让我的文本在标签内移动,以便用户可以看到整个文本。 例如:假设我的文字长度为20个字符,我的标签有足够的空间,只有15个字符。我想要的是我的标签显示前15个字符(字符1-15)然后1秒后相同的字符没有第一个但最后一个(所以字符2-16)然后下一个(字符3-17) )等等,直到最后15个字符(字符5-20),然后我希望它们从头开始(字符1-15再次)。
我该怎么做?一种方法(显然)使用Timer,但我确信存在更优雅的解决方案。
答案 0 :(得分:2)
下面是一个快速和脏的滚动控件的代码,一旦用户将鼠标悬停在控件上,它就应该按照你想要的那样做。
<Canvas Name="brd"
ClipToBounds="True"
Margin="10"
Height="20" Width="150"
Background="White"
HorizontalAlignment="Left">
<StackPanel Name="spl1"
Orientation="Horizontal"
Canvas.Left="0">
<TextBlock Name="tbk1"
Margin="10,0"
MinWidth="{Binding ElementName=brd,Path=ActualWidth}"
Text="A display of test text that is wider than the control."/>
<TextBlock MinWidth="{Binding ElementName=brd,Path=ActualWidth}"
Margin="10,0"
Text="{Binding ElementName=tbk1,Path=Text}"/>
</StackPanel>
<Canvas.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Name="scroll">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation To="-200" Duration="0:0:4"
Storyboard.TargetName="spl1"
Storyboard.TargetProperty="(Canvas.Left)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<StopStoryboard BeginStoryboardName="scroll"/>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
为了正确操作,您需要更改一部分,我没有实现。 <DoubleAnimation To="-200"...
需要更改。理想情况下,To
的值将是ActualWidth
控件的tbk1
属性的负数。这将需要元素绑定来获取值,并ValueConverter
使该值为负值。
如果您不想解决转换器的问题,可以将To
值设置得足够大,以容纳您期望的最长文本。那会让你相当接近。
当然,您可以进行更多调整,以便在一个动画周期结束时和下一个动画周期开始时提供更平滑的过渡。
修改强>
好的,我不能把它完成一半。下面是更新的XAML以便顺利操作,以及ValueConverter
的包含代码。
<Window.Resources>
<Converters:ChangeSignConverter x:Key="ChangeSignConverter"/>
</Window.Resources>
<Canvas Name="brd"
ClipToBounds="True"
Margin="10"
Height="20" Width="150"
Background="White"
HorizontalAlignment="Left">
<StackPanel Name="spl1"
Margin="5,0,0,0"
Orientation="Horizontal"
Canvas.Left="0">
<TextBlock Name="tbk1"
Padding="0,0,10,0"
MinWidth="{Binding ElementName=brd,Path=ActualWidth}"
Text="A display of test text that is wider than the control."/>
<TextBlock MinWidth="{Binding ElementName=brd,Path=ActualWidth}"
Text="{Binding ElementName=tbk1,Path=Text}"/>
</StackPanel>
<Canvas.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Name="scroll">
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation To="{Binding ElementName=tbk1,Path=ActualWidth,Converter={StaticResource ChangeSignConverter}}"
Duration="0:0:4"
Storyboard.TargetName="spl1"
Storyboard.TargetProperty="(Canvas.Left)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<StopStoryboard BeginStoryboardName="scroll"/>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
转换器类:
class ChangeSignConverter : IValueConverter
{
object IValueConverter.Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert.ToDouble(value) * -1;
}
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Convert.ToDouble(value) * -1;
}
}
答案 1 :(得分:1)
您还可以使用WPF animation功能。您创建一个自定义控件,其中包含一个TextBlock。定义控件的宽度(它将小于文本块的宽度。然后定义故事板和双动画以根据需要设置动画(更慢/更快,仅动画到右边,动画然后左边等等)。
这只是一个想法。我现在很匆忙,但如果你需要,我可以为你提供额外的代码。
答案 2 :(得分:0)
我还会将Timer用于您描述的功能。如果你坚持在某个指定的时间间隔内更改Label,我认为没有太多其他解决方案。另一方面,我可能会使用ToolTip,我认为这更直观。