0

テキストが収まらないラベルがいくつかある C# アプリケーションに WPF を使用しています。私が望むのは、ユーザーがテキスト全体を見ることができるように、テキストをラベル内で移動させることです。例 : 私のテキストの長さは 20 文字で、私のラベルでは 15 文字だけの十分なスペースがあるとします。私が望むのは、最初の 15 文字 (文字 1 ~ 15) をラベルに表示し、1 秒後に最初の文字を除いて同じ文字を表示し、最後に別の文字 (文字 2 ~ 16) を表示し、次に次 (文字 3 ~ 17) を表示することです。 ) などを最後の 15 文字 (文字 5 ~ 20) まで続けてから、最初 (文字 1 ~ 15) から開始するようにします。

どうやってやるの ?1 つの方法は (明らかに) タイマーを使用することですが、より洗練されたソリューションが存在すると確信しています。

4

3 に答える 3

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>

適切な操作のために変更する必要がある部分が 1 つありますが、実装していません。<DoubleAnimation To="-200"...を変更する必要があります。の値は、コントロールのプロパティのTo負の値になるのが理想的です。これには、値を取得するための要素バインディングと、その値を負にするための の両方が必要になります。ActualWidthtbk1ValueConverter

コンバーターの手間をかけたくない場合は、To予想される最も長いテキストに対応できるように、値を十分に大きくすることができます。それはあなたをかなり近くに連れて行きます。

もちろん、これをさらに微調整して、1 つのアニメーション サイクルの終了時と次の開始時のトランジションをよりスムーズにすることもできます。

編集

OK、中途半端なままにしておくことはできませんでした。以下は、スムーズな操作のために更新された 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;
  }
}
于 2013-10-04T16:12:39.020 に答える
1

WPFアニメーション機能を使用することもできます。内部に TextBlock を持つカスタム コントロールを作成します。コントロールの幅を定義します (これはテキストブロックの幅よりも小さくなります。次に、ストーリーボードとダブル アニメーションを定義して、必要に応じてアニメーション化します (遅い/速い、右にのみアニメーション化、右にアニメーション化してから左にアニメーション化するなど)。

これは単なるアイデアです。現在急いでいますが、必要な場合は追加のコードを提供できます。

于 2013-10-04T15:04:14.070 に答える
0

あなたが説明した機能にもタイマーを使用します。指定された時間間隔でラベルを変更することを主張する場合、他の解決策はあまりないと思います。一方で、おそらく ToolTip を使用すると思いますが、これはより直感的だと思います。

于 2013-10-04T15:01:32.377 に答える