前言
在本文中,我们将使用C#和WPF一个简单的二进制时钟。该项目本身将有助于表现出一定的特殊性,如使用任务,如何操纵一个WPF页面的UI和基本的数据转换。
介绍
二进制时钟是显示在二进制格式的当前时间的时钟。在下面的例子中,我们将创建一组图形发光二极管,其每一个将代表一个二进制数位的。每个LED可在两种状态进行设置:(这表示1的值)或关闭(这代表零值)。从右到左,我国LED将代表值1,2,4,8,16,32,因为我们将立足于24小时格式的时间我们的转换,我们需要有大量数字可以代表最多的十进制值60(分钟和秒钟)。
的当前时间(小时,分,秒),每个部分将具有其自身的六个LED行,以表示十进制值的二进制转换。例如,如果我们想显示像10时33分42秒时间,我们的LED灯必须按照以下方式亮起:
在XAML中的二进制时钟
上述概念的XAML渲染相当简单。在一个新的XAML页,我们需要创建矩形,其圆角半径将被设置为50,得到它们的圆形形状的三行。其它的设置将参照填充颜色,形状阴影,等等,以绘制导致我们所希望的方式。在我们的例子中,LED将根据下面的XAML代码被隐藏和有色:
<Rectangle HorizontalAlignment="Left" Height="35" Margin="211,40,0,0"
Stroke="#FF033805" VerticalAlignment="Top"
Width="38" RadiusX="50" RadiusY="50">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="10"/>
</Rectangle.Effect>
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFFFFF1B" Offset="0"/>
<GradientStop Color="#FF29B413" Offset="0.568"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
一旦完成了创建每一行对我们的用户界面,并且具有点缀应有尽有,XAML页面看起来就像这样:
你可以参考下载部分,可在文章上面的代码片段的完整参考的结束。
源代码
以下部分解释了我们的矩形如何进行控制,以显示当前时间的二进制表示。
在我们的XAML窗口中,我们已经声明事件调用-更准确地说,必须在页面装载(Loaded事件)被解雇的事件。在的代码隐藏Window_Loaded
常规,我们执行两个主要的操作:第一种是仅仅是图形化的,并且由每一个长方形的不透明度设置为0.35
,为了给领导的关断的印象。第二个是将执行计算和更新UI的任务的执行。后来更多。首先,让我们看看如何识别一个XAML页面上声明的控制。
让我们来看看在循环的所有矩形的不透明度设置为0.35
:
// 设置所有的矩形不透明度为0.35
foreach (var r in LogicalTreeHelper.GetChildren(MainGrid))
{
if (r is Rectangle) (r as Rectangle).Fill.Opacity = 0.35;
}
谈到识别控制,WinForms和WPF之间的主要区别是,我们不能使用属性是指容器的控制控件()
。做那种手术的WPF的方式通过LogicalTreeHelper
类。通过它,我们可以在方法调用的GetChildren
,表明其找回孩子控制主控的名称。在我们的例子中,我们已经执行LogicalTreeHelper.GetChildren
在控制MainGrid
(标识的名称格
我们的XAML页面的对象)。然后,在遍历数组的控制,我们检查,如果那个特定的控制是一个矩形
和-如果有的话-我们将其不透明度设置为需要的值进行。
第二组从所述的指令Window_Loaded
事件是次要任务的计算每个时间部分的二进制表示,并更新UI以及执行。的代码如下:

Task.Factory.StartNew(() =>
{
// while the thread is running...
while (true)
{
// ...get the current system time
DateTime _now = System.DateTime.Now;
// Convert each part of the system time (i.e.: hour, minutes, seconds) to
// binary, filling with 0s up to a length of 6 char each
String _binHour = Convert.ToString(_now.Hour, 2).PadLeft(6, '0');
String _binMinute = Convert.ToString(_now.Minute, 2).PadLeft(6, '0');
String _binSeconds = Convert.ToString(_now.Second, 2).PadLeft(6, '0');
// For each digit of the binary hour representation
for (int i = 0; i <= _binHour.Length - 1; i++)
{
// Dispatcher invoke to refresh the UI, which belongs to the main thread
H0.Dispatcher.Invoke(() =>
{
// Update the contents of the labels which use decimal h/m/s representation
lbHour.Content = _now.Hour.ToString("00");
lbMinute.Content = _now.Minute.ToString("00");
lbSeconds.Content = _now.Second.ToString("00");
// Search for a rectangle which name corresponds to the _binHour current char index.
// Then, set its opacity to 1 if the current _binHour digit is 1, or to 0.35 otherwise
(MainGrid.FindName("H" + i.ToString()) as Rectangle).Fill.Opacity =
_binHour.Substring(i, 1).CompareTo("1") == 0 1 : 0.35;
(MainGrid.FindName("M" + i.ToString()) as Rectangle).Fill.Opacity =
_binMinute.Substring(i, 1).CompareTo("1") == 0 1 : 0.35;
(MainGrid.FindName("S" + i.ToString()) as Rectangle).Fill.Opacity =
_binSeconds.Substring(i, 1).CompareTo("1") == 0 1 : 0.35;
});
}
}
});
不言自明,任务由一个永无止境的循环,它不断地检索当前系统时间。然后,它在它的三个主要部分分隔它(小时,分,秒),并在将它们转换为它们的二进制表示,通过使用所得Convert.ToString()
功能,我们将通过用于转换的数字基(在本例中,2
)。因为我们需要三个串
长度等于六(我们有六个LED为每个行)的S,我们需要垫每串
多达六个字符。所以,如果,例如,我们正在转换的值5
,函数将产生101
作为输出-值我们将垫000101
。
该工程至二进制的长度的第二循环串
有关小时(一值,该值将是有史以来SIX),将提供用户界面更新,使用分派器
属性来调用更新
运行于另一个线程的对象的方法(请参考“ VB.NET:调用方法从辅助线程更新UI »关于进一步详情调用
方法)。对于包含在我们的每个数字串
S,我们需要找出正确的矩形
,以更新其不透明度值。
我们可以通过完成这样的任务FindName()
函数:给定一个父对象(MainGrid
,在我们的例子),FindName
将继续在提到一个UI控件,如果传递的参数对应于一个存在的控件名称。既然我们已经命名与一个渐进的数量,每次部分矩形(0
至5
,开头ħ
几个小时,中号
为分钟,小号
为秒),我们可以要求函数检索其名称与特定开始控制信,并继续以等于当前的二进制字符串索引的索引。
让我们来看看这些线清晰起见之一:与以下行:
(MainGrid.FindName("H" + i.ToString()) as Rectangle).Fill.Opacity =
_binHour.Substring(i, 1).CompareTo("1") == 0 1 : 0.35;
我们都在问:从检索MainGrid
其名称等于“控制^ h
”+当前循环索引。认为这是一个矩形
,然后将其不透明度
根据以下规则:如果从二进制索引字符串
是1
,则该不透明度
必须1
,否则它必须被设置为0.35
。执行该程序,将导致什么可以在下面的视频中可以看出。
示范视频
下载
对于本文示例的完整源代码可以在下载https://code.msdn.microsoft.com/Binary-Clock-in-C-and-WPF-f954c9a5。