当用户单击我控件中的某些位置时,我想更改网格中某些行和列的颜色,然后在大约 500 毫秒内将其淡化回正常颜色。我还没有决定是使用 Winforms 还是 WPF,所以任何一种技术的建议都可以。谢谢你。
编辑:我知道我可以通过在单击事件中循环调用 Paint 来正确设置绘图参数来做到这一点。但是我相信这会阻止用户界面,我希望比这更敏感。
WPF 对动画有很好的支持。xaml 和背后的代码都支持动画,因此您应该能够实现您想要的任何外观。
WPF的 MSDN动画概述看起来有很多很好的信息可以帮助您入门。
这是处理淡入淡出的一种方法:
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
{
public class FadeForm : Form
{
private Timer fadeTimer;
private Panel fadePanel;
private Button fadeButton;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose( bool disposing )
{
if ( disposing && ( components != null ) )
{
components.Dispose();
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.fadePanel = new System.Windows.Forms.Panel();
this.fadeButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// fadePanel
//
this.fadePanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.fadePanel.Location = new System.Drawing.Point( 4, 8 );
this.fadePanel.Name = "fadePanel";
this.fadePanel.Size = new System.Drawing.Size( 276, 104 );
this.fadePanel.TabIndex = 0;
//
// fadeButton
//
this.fadeButton.Location = new System.Drawing.Point( 104, 116 );
this.fadeButton.Name = "fadeButton";
this.fadeButton.Size = new System.Drawing.Size( 75, 23 );
this.fadeButton.TabIndex = 1;
this.fadeButton.Text = "Fade";
this.fadeButton.UseVisualStyleBackColor = true;
this.fadeButton.Click += new System.EventHandler( this.HandleFadeButtonClick );
//
// FadeForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF( 6F, 13F );
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size( 284, 142 );
this.Controls.Add( this.fadeButton );
this.Controls.Add( this.fadePanel );
this.Name = "FadeForm";
this.Text = "Fade Form";
this.ResumeLayout( false );
}
#endregion
public FadeForm()
{
InitializeComponent();
this.fadeTimer = new Timer();
}
private void HandleFadeButtonClick( object sender, EventArgs e )
{
this.fadeTimer.Tick += new EventHandler( HandleFadeTimerTick );
this.fadePanel.BackColor = Color.Red;
this.fadeTimer.Interval = 100;
this.fadeTimer.Start();
}
void HandleFadeTimerTick( object sender, EventArgs e )
{
Color panelColor = this.fadePanel.BackColor;
if ( panelColor.A > 0 )
{
this.fadePanel.BackColor =
Color.FromArgb(
Math.Max( panelColor.A - 20, 0 ),
panelColor.R, panelColor.G, panelColor.B );
}
else
{
this.fadeTimer.Stop();
}
}
}
}
不幸的是,这种方法似乎不适用于 DataGridView 中的行。我不知道原因,但是如果颜色的 alpha 分量不是 255,则颜色根本不会显示。如果您能找到解决方法,此代码可能会有所帮助。
在最简单的情况下,像这样的淡入淡出效果只需要某种计时器,每次滴答都会使颜色恢复正常。时间越快,您从头到尾显示的离散颜色越多,整体效果就越平滑(WPF 可能有内置的东西来做到这一点)。
您绝对不想循环重绘。正如您指出的那样,这将阻塞 UI,并且您将无法控制循环需要多长时间(不同的机器将在不同的时间长度内将相同数量的步骤从高亮颜色渲染到正常)。