我正尝试在我的WPF应用程序中模拟LED指示灯(大约16个)。我从串口获得2个字节,根据这些位,我需要打开/关闭应用程序窗口上的LED指示灯。示例: 0xFF、0xFE =>除最后一个指示灯外,所有指示灯均亮起。我使用带有深色背景颜色的标签来指示关闭LED,而使用明亮的背景颜色来指示ON LED。如果我有一个标签数组,那么我可能会这样做:
for(i = 0; i < 16; i++)
{
if(bitArray[i] == true)
lblLED[i].Background = Brushes.Pink;
else
lblLED[i].Background = Brushes.Maroon;
}有什么建议是最好的方法吗?一个示例代码,可以说明这是如何工作的将是有帮助的。谢谢!
发布于 2012-12-21 08:44:58
涵盖的概念是INotifyPropertyChanges (在.net 4.5中(在其他版本中有最小的变化,但概念相同),ItemsControl和finally样式触发器。
INotifyPropertyChanges
我的第一步是将INotifyPropertyChanges放在我们的主窗口上,以便自动通知WPF控件任何更改。您将把您的位数组转换为一个列表,并简单地将其放入(也许是在计时器上?)在需要的时候。请注意,无论有多少are...the控件将展开,这都无关紧要。
public partial class MainWindow : Window, INotifyPropertyChanged
{
private List<bool> _LedStates;
public List<bool> LedStates
{
get { return _LedStates; }
set
{
_LedStates = value;
NotifyPropertyChanged();
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
LedStates = new List<bool>() {true, false, true};
}
#region INotifyPropertyChanged
/// <summary>
/// Event raised when a property changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the PropertyChanged event.
/// </summary>
/// <param name="propertyName">The name of the property that has changed.</param>
protected virtual void NotifyPropertyChanged( [CallerMemberName] String propertyName = "" )
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler( this, new PropertyChangedEventArgs( propertyName ) );
}
}
#endregion
}ItemsControl样式触发器(&S)
然后,在WPF xaml中,我们将绑定到bool列表并使用项模板(考虑为找到的每个数据项使用一个通用的迷你视图)。在该模板中,我们将根据布尔值的状态显示红色或绿色。
不需要转换器,因为我们设置了一个样式触发器,它是调整到一个目标值。如果文本块文本为"True“,我们将显示绿色,如果为"False”,我们将触发/显示红色。
<Window x:Class="WPFBindToArray.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ItemsControl x:Name="icBitViewer"
ItemsSource="{Binding LedStates}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel HorizontalAlignment="Stretch"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Grid.Column="0">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="Text" Value="True">
<Setter Property="Background" Value="Green" />
</Trigger>
<Trigger Property="Text" Value="False">
<Setter Property="Background" Value="Red" />
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>当这个程序在这里运行时,结果是:

发布于 2012-12-21 08:07:30
我相信你能想出怎么做你所要求的,但是让我们考虑一下手头的工具?看起来,你有一个布尔数组。正如所建议的,ItemsControl可以很好地处理它们。首先,让我们做一些代码隐藏,将bool转换为画笔来设置项目的背景。
using System;
using System.Windows.Media;
using System.Windows.Data;
using System.Globalization;
namespace MyNamespace
{
public class BoolToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// return a Pink SolidColorBrush if true, a Maroon if false
return (bool)value ? Brushes.Pink : Brushes.Maroon;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (SolidColorBrush)value == Brushes.Pink;
}
}
}这将允许您在绑定到ItemsControl时将bool[] bitArray转换为一系列笔刷。现在来看一些Xaml:
首先,确保在xmlns属性和System Core Library (请参阅xmlns属性)中声明本地名称空间(其中包含我们刚刚定义的转换器)。
<Window x:Class="MyNamespace.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<!-- our local namespace -->
xmlns:my="clr-namespace:MyNamespace"
<!-- system core library -->
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="600" Width="900">
<Grid>
<ItemsControl Name="LEDPanel"> <!-- Need to Name this Control in order to set the ItemsSource Property at startup -->
<ItemsControl.Resources>
<my:BoolToBrushConverter x:Key="LEDConverter" /> <!-- Here we define our converter for use, note the preceding my: namespace declaration -->
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" /> <!-- this will make the items defined in the ItemTemplate appear in a row -->
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Boolean}"> <-- We will be binding our ItemsControl to a bool[] so each Item will be bound to a bool -->
<Border Margin="3" CornerRadius="10" Height="20" Width="20" BorderThickness="2" BorderBrush="Silver" Background="{Binding Converter={StaticResource LEDConverter}}" />
<!-- This is where we describe our item. I'm drawing a round silver border and then binding the Background to the item's DataContext (implicit) and converting the value using our defined BoolToBrushConverter -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>编辑:我忘记了DataBinding。在窗口的构造函数中:
public MainWindow()
{
InitializeComponent();
LEDPanel.ItemsSource = bitArray;
}发布于 2012-12-21 07:33:25
尝尝这个。这显然只是一个例子,我建议你使用WPF的功能,也许使用一个不同于Label的控件。
Func<ushort, bool[]> getBits = s =>
{
var bools = new bool[sizeof (ushort)*8];
for (var i = 0; i < bools.Length; i++)
bools[i] = (s & 1 << i) > 0;
return bools;
};
var bits = getBits(2);
var labels = new Label[sizeof (ushort)*8];
for (var i = 0; i < labels.Length; i++)
{
var label = new Label {Background = bits[i] ? Brushes.Green : Brushes.Red};
labels[i] = label;
}
//Do something with the Label arrayhttps://stackoverflow.com/questions/13981958
复制相似问题