c\#WPF 는 스크롤 디 스 플레이 의 TextBlock 을 어떻게 실현 합 니까?

우리 가 TextBlock 을 사용 하여 데 이 터 를 표시 할 때 이러한 상황 을 자주 만 날 수 있 습 니 다.바로 TextBlock 의 문자 내용 이 너무 많 습 니 다.모두 표시 하면 대량의 화면 을 차지 합 니 다.이것 은 우리 가 일부분 만 표시 하고 다른 일부분 은 시간 이 지 날수 록 스크롤 하여 표시 합 니 다.그러나 WPF 가 기본적으로 제공 하 는 TextBlock 은 이런 기능 을 갖 추 지 못 한다 면 어떻게 실현 할 것 인가?
사실은 개인 적 으로 사고방식 이 비교적 명확 하 다 고 생각 합 니 다.바로 자신 이 UserControl 을 정의 한 다음 에 WPF 의 간단 한 요 소 를 조합 하여 최종 적 으로 사용자 정의 컨트롤 을 실현 하 는 것 입 니 다.그래서 우 리 는 이 사고방식 에 따라 쉽게 실현 할 수 있 습 니 다.Canvas 라 는 컨트롤 은 Left,Top,Right,Bottom 속성 을 설정 하여 하위 컨트롤 의 위 치 를 정확하게 제어 할 수 있다 는 것 을 알 고 있 습 니 다.그러면 분명히 이 컨트롤 이 필요 합 니 다.또한 캔버스 용기 에 TextBlock 컨트롤 을 설치 하고 TextWrapping="Wrap"을 설정 하여 모든 문 자 를 표시 합 니 다.물론 이 안에 스크롤 을 시 키 려 면 TextBlock 의 높이 가 Canvas 의 높이 를 초과 해 야 의미 가 있 습 니 다.또 하나의 중요 한 부분 은 Canvas 의 ClipToBounds='True'라 는 속성 을 설정 하 는 것 입 니 다.이렇게 초과 한 부분 은 표시 되 지 않 습 니 다.구체 적 인 실현 방향 은 코드 를 참조 하여 제 가 다시 한 번 진지 하 게 분석 하 겠 습 니 다!
1.RollingTextBlock 이라는 UserControl 을 새로 만 듭 니 다.

<UserControl x:Class="TestRoilingTextBlock.RoilingTextBlock"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             DataContext="{Binding RelativeSource={RelativeSource Self}}"
             mc:Ignorable="d" d:DesignWidth="300" Height="136" Width="400">
    <UserControl.Template>
        <ControlTemplate TargetType="UserControl">
            <Border BorderBrush="Gray"
                    BorderThickness="1"
                    Padding="2"
                    Background="Gray">
                <Canvas x:Name="innerCanvas"
                        Width="Auto"
                        Height="Auto"
                        Background="AliceBlue"
                        ClipToBounds="True">
                    <TextBlock x:Name="textBlock"
                               Width="{Binding ActualWidth,ElementName=innerCanvas}" 
                               TextAlignment="Center"
                               TextWrapping="Wrap"
                               Height="Auto"
                               ClipToBounds="True"
                               Canvas.Left="{Binding Left,Mode=TwoWay}"
                               Canvas.Top="{Binding Top,Mode=TwoWay}"
                               FontSize="{Binding FontSize,Mode=TwoWay}"
                               Text="{Binding Text,Mode=TwoWay}"
                               Foreground="{Binding Foreground,Mode=TwoWay}">
 
                    </TextBlock>
                </Canvas>
 
            </Border>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>
여기 서 몇 가지 중요 한 지식 점 을 분석 합 니 다.A:DataContext="{Binding RelativeSource={RelativeSource Self}"이것 은 현재 프론트 바 인 딩 데이터 원본 입 니 다.이것 은 첫 번 째 단계 이자 기초 입 니 다.B 는 현재 TextBlock 에 Text,Canvas.Left,Canvas.Top,Width 등 속성 을 연결 합 니 다.물론 이 속성 들 은 자신의 필요 와 결합 하여 연결 하고 배경 에서 관련 의존 항목 속성 을 정의 해 야 합 니 다.
     그리고 배경 에 있 는 논리 코드 를 보 세 요.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
 
namespace TestRoilingTextBlock
{
    /// <summary>
    /// RoilingTextBlock.xaml      
    /// </summary>
    public partial class RoilingTextBlock : UserControl
    {
        private bool   canRoll = false;
        private double rollingInterval = 16;//       
        private double offset=6;//      
        private TextBlock currentTextBlock = null;       
        private DispatcherTimer currentTimer = null;
        public RoilingTextBlock()
        {
            InitializeComponent();
            Loaded += RoilingTextBlock_Loaded;
        }
 
        void RoilingTextBlock_Loaded(object sender, RoutedEventArgs e)
        {
            if (this.currentTextBlock != null)
            {
                canRoll = this.currentTextBlock.ActualHeight > this.ActualHeight;
            }
            currentTimer = new System.Windows.Threading.DispatcherTimer();
            currentTimer.Interval = new TimeSpan(0, 0, 1);
            currentTimer.Tick += new EventHandler(currentTimer_Tick);
            currentTimer.Start();
        }
 
        public override void OnApplyTemplate()
        {
            try
            {
                base.OnApplyTemplate();
                currentTextBlock = this.GetTemplateChild("textBlock") as TextBlock;
            }
            catch (Exception ex)
            {               
               
            }
              
        }
 
        void currentTimer_Tick(object sender, EventArgs e)
        {
            if (this.currentTextBlock != null && canRoll)
            {
                if (Math.Abs(Top) <= this.currentTextBlock.ActualHeight-offset)
                {
                    Top-=rollingInterval;
                }
                else
                {
                    Top = this.ActualHeight;
                }
 
            }
        }
 
        #region Dependency Properties
        public static DependencyProperty TextProperty =
           DependencyProperty.Register("Text", typeof(string), typeof(RoilingTextBlock),
           new PropertyMetadata(""));
 
        public static DependencyProperty FontSizeProperty =
            DependencyProperty.Register("FontSize", typeof(double), typeof(RoilingTextBlock),
            new PropertyMetadata(14D));       
 
        public static readonly DependencyProperty ForegroundProperty =
           DependencyProperty.Register("Foreground", typeof(Brush), typeof(RoilingTextBlock), new FrameworkPropertyMetadata(Brushes.Green));
 
        public static DependencyProperty LeftProperty =
           DependencyProperty.Register("Left", typeof(double), typeof(RoilingTextBlock),new PropertyMetadata(0D));
 
        public static DependencyProperty TopProperty =
           DependencyProperty.Register("Top", typeof(double), typeof(RoilingTextBlock),new PropertyMetadata(0D));
     
        #endregion
 
        #region Public Variables
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
 
        public double FontSize
        {
            get { return (double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }
 
        public Brush Foreground
        {
            get { return (Brush)GetValue(ForegroundProperty); }
            set { SetValue(ForegroundProperty, value); }
        }
 
        public double Left
        {
            get { return (double)GetValue(LeftProperty); }
            set { SetValue(LeftProperty, value); }
        }
 
        public double Top
        {
            get { return (double)GetValue(TopProperty); }
            set { SetValue(TopProperty, value); }
        }
        #endregion
    }
}
백 엔 드 코드 를 보십시오.여기 서 우 리 는 단지 타이머 로 1 초 간격 으로 TextBlock 이 Canvas 에 있 는 위 치 를 업데이트 할 뿐 입 니 다.이 안 에는 현재 TextBlock 의 Actual Height 를 어떻게 얻 는 지 주의해 야 할 지식 이 있 습 니 다.우 리 는 기본 클래스 의 OnApply Template 를 다시 쓰 는 방법 으로 얻 을 수 있 습 니 다.또한 이 방법 은 프론트 와 백 엔 드 의 결합 이 존재 합 니 다.바 인 딩 을 통 해 TextBlock 의 Actual Height 를 얻 을 수 있 습 니까?바 인 딩 을 통 해 무엇 을 주의해 야 합 니까?그 중에서 특히 주의해 야 할 것 은 Actual Height 는 요소 가 다시 그 려 진 사 이 즈 를 나타 내 고 읽 기만 하 는 것 입 니 다.즉,항상 실제 값 입 니 다.바 인 딩 할 때 의존 적 인 속성 에 Set 를 추가 할 수 없고 바 인 딩 할 때 바 인 딩 하 는 모드 는 기본 모드 가 아 닌 Mode="One Way ToSource"일 수 있 습 니 다.
또한 타 이 머 를 사용 할 때 왜 System.Windows.Threading.DispatcherTimer 를 System.Timers.Timer 가 아 닌 System.Windows.Threading.DispatcherTimer 를 사용 합 니까?이 는 우리 가 원인 을 진지 하 게 분석 해 야 WPF 를 제대로 배 울 수 있다.
물론 본 고 는 간단 한 사 고 를 제공 할 뿐 뒤에 확장 할 수 있 는 부분 이 많다.예 를 들 어 매번 이동 하 는 거 리 를 어떻게 확정 하고 이동 하 는 속 도 는 얼마 입 니까?이것 이 풍부 하면 많은 내용 이 있 습 니 다.이것 은 구체 적 인 프로젝트 의 수요 에 따라 확장 해 야 합 니 다.여 기 는 가장 간단 한 방식 을 제공 하고 하나의 방향 만 제공 해 야 합 니 다.
2 현재 사용자 정의 RollingTextBlock 을 어떻게 참조 합 니까?

<Window x:Class="TestRoilingTextBlock.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:TestRoilingTextBlock"
        Title="MainWindow" Height="550" Width="525">
    <Grid>
        <local:RoilingTextBlock Foreground="Teal"
                                Text="       ,       。       ,       。       ,       。       ,       。       ,       。
                                       ,       。       ,       。       ,       。"
                                FontSize="22">           
        </local:RoilingTextBlock>
 
    </Grid>
</Window>
3 마지막 으로 최종 효 과 를 살 펴 보 자.물론 데 이 터 는 계속 굴 러 가 는 상태 이 고 여기 에는 그림 한 장만 붙 여 져 있다.

이상 은 c\#WPF 가 스크롤 디 스 플레이 의 TextBlock 을 어떻게 실현 하 는 지 에 대한 상세 한 내용 입 니 다.WPF 가 스크롤 디 스 플레이 를 실현 하 는 TextBlock 에 관 한 자 료 는 다른 관련 글 을 주목 하 십시오!

좋은 웹페이지 즐겨찾기