none
Плавная смена текста в Label на C# RRS feed

  • Вопрос

  • Добрый вечер, возникла проблема.

    Задача: Label заполняется по таймеру из xml файла случайными значениями, необходимо менять текст в label плавно (что бы он погасал -> менялся текст -> и возвращался обратно)

    Я делаю так:

            private void ScreenSaverForm_Load(object sender, EventArgs e)
            {
    //...
    moveTimer.Interval = 3000;
                moveTimer.Tick += new EventHandler(moveTimer_Tick);
                moveTimer.Start();
            }
    
            private void moveTimer_Tick(object sender, EventArgs e)
            {
                _timer.Interval = 500;
                _timer.Tick += new EventHandler(_timer_Tick);
                _timer.Enabled = true;
    
                int id = rand.Next(0, 2);
                string str = document.GetElementsByTagName("Item")[id].ChildNodes[0].InnerText;
                string name = document.GetElementsByTagName("Item")[id].ChildNodes[1].InnerText;
                mainLabel.Text = str;
                nameLabel.Text = name;
                for (int i = 0; i < 100; i += 10)
                {
                    _timer.Start();
                    mainLabel.ForeColor = Color.FromArgb(i, mainLabel.ForeColor);
                }
            }
    
            private void _timer_Tick(object sender, EventArgs e)
            {
                int A = 0;
                mainLabel.ForeColor = Color.FromArgb(A, mainLabel.ForeColor);
    
                A -= 10;
                if (A < 0)
                    _timer.Enabled = false;
            }

    Но это не работает. Не могу понять почему. Буду рад любой помощи.

    29 октября 2012 г. 17:59

Ответы

  • Добрый день.

    Насколько я понял, у вас смена цвета планировалась вот в этом цикле:

    for (int i = 0; i < 100; i += 10)
    {
       _timer.Start();
       mainLabel.ForeColor = Color.FromArgb(i, mainLabel.ForeColor);
    }

    Но он отрабатывает очень быстро и соответственно, без передачи управления на перерисовку... Т.к. вы не сказали, какое у вас приложение (WinForms или WPF), то давайте покажу, как это будет в WinForms.

    На форму, я кинул label и button. У кнопки добавил обработчик клика. Вот код формы:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            dR = label1.BackColor.R - label1.ForeColor.R;
            dG = label1.BackColor.G - label1.ForeColor.G;
            dB = label1.BackColor.B - label1.ForeColor.B;
            sign = 1;
            Timer timer = new Timer();
            timer.Interval = 100;
            timer.Tick += timer_Tick;
            timer.Start();
        }
        int dR, dG, dB, sign;
        void timer_Tick(object sender, EventArgs e)
        {
            if (Math.Abs(label1.ForeColor.R - label1.BackColor.R) < Math.Abs(dR / 10))
            {
                sign *= -1;
                label1.Text = "Новый текст";
            }            
            label1.ForeColor = Color.FromArgb(255, label1.ForeColor.R + sign * dR / 10, label1.ForeColor.G + sign * dG / 10, label1.ForeColor.B + sign * dB / 10);
            if (label1.BackColor.R == label1.ForeColor.R + dR)
            {
                ((Timer)sender).Stop();
            }
        }
    }

    При запуске приложения, в label один текст. После нажатия на кнопку, он блекнет, потом проявляется новый текст. Вся анимация занимает 2 секунды...

    p.s. Если хотите писать красивости в пользовательском интерфейсе, переходите на XAML, там все это намного проще...

    • Помечено в качестве ответа mr_arti 30 октября 2012 г. 12:09
    30 октября 2012 г. 9:09
    Отвечающий

Все ответы

  • Добрый день.

    Насколько я понял, у вас смена цвета планировалась вот в этом цикле:

    for (int i = 0; i < 100; i += 10)
    {
       _timer.Start();
       mainLabel.ForeColor = Color.FromArgb(i, mainLabel.ForeColor);
    }

    Но он отрабатывает очень быстро и соответственно, без передачи управления на перерисовку... Т.к. вы не сказали, какое у вас приложение (WinForms или WPF), то давайте покажу, как это будет в WinForms.

    На форму, я кинул label и button. У кнопки добавил обработчик клика. Вот код формы:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            dR = label1.BackColor.R - label1.ForeColor.R;
            dG = label1.BackColor.G - label1.ForeColor.G;
            dB = label1.BackColor.B - label1.ForeColor.B;
            sign = 1;
            Timer timer = new Timer();
            timer.Interval = 100;
            timer.Tick += timer_Tick;
            timer.Start();
        }
        int dR, dG, dB, sign;
        void timer_Tick(object sender, EventArgs e)
        {
            if (Math.Abs(label1.ForeColor.R - label1.BackColor.R) < Math.Abs(dR / 10))
            {
                sign *= -1;
                label1.Text = "Новый текст";
            }            
            label1.ForeColor = Color.FromArgb(255, label1.ForeColor.R + sign * dR / 10, label1.ForeColor.G + sign * dG / 10, label1.ForeColor.B + sign * dB / 10);
            if (label1.BackColor.R == label1.ForeColor.R + dR)
            {
                ((Timer)sender).Stop();
            }
        }
    }

    При запуске приложения, в label один текст. После нажатия на кнопку, он блекнет, потом проявляется новый текст. Вся анимация занимает 2 секунды...

    p.s. Если хотите писать красивости в пользовательском интерфейсе, переходите на XAML, там все это намного проще...

    • Помечено в качестве ответа mr_arti 30 октября 2012 г. 12:09
    30 октября 2012 г. 9:09
    Отвечающий
  • Я так понимаю, основной затык был в том, что Contor.ForeColor не понимает Alpha-канал.
    30 октября 2012 г. 9:56
  • Я так понимаю, основной затык был в том, что Contor.ForeColor не понимает Alpha-канал.

    И это конечно тоже, но основная идея в том, что изменения свойств должны идти не в цикле и за доли секунды, а через таймер и хоть какое то время, которое будет различать пользователь...
    30 октября 2012 г. 10:08
    Отвечающий
  • Большое вам спасибо, это то что мне и нужно было :) Та да надо начать изучать XAML.
    30 октября 2012 г. 12:10