1

WPFアプリ(約16)でLEDインジケーターをシミュレートしようとしています。シリアルポートから2バイトを取得し、そのビットに基づいて、アプリウィンドウのLEDインジケーターをオン/オフにする必要があります。例:0xFF、0xFE=>最後のLEDを除くすべてがオンになっています。オフLEDを示すために暗い背景色、オンLEDを示すために明るい背景色のラベルを使用しています。ラベルの配列がある場合は、次のようなことができます。

for(i = 0; i < 16; i++)
{
  if(bitArray[i] == true)
    lblLED[i].Background = Brushes.Pink;
  else
    lblLED[i].Background = Brushes.Maroon;
}

これを行うための最良の方法について何か提案はありますか?これがどのように機能するかを示すことができるサンプルコードが役立ちます。ありがとう!

4

3 に答える 3

2

あなたが求めていることを行う方法を理解できると確信していますが、手元にあるツールについて考えてみましょう。あなたはboolの配列を持っているようです。提案されたように、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;
        }
    }
}

bool[] bitArrayこれにより、 にバインドされたときに、 を一連のブラシに変換できますItemsControl。Xaml の場合:

最初に、xmlns 属性とシステム コア ライブラリ (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 を忘れました。Window のコンストラクターで:

public MainWindow()
{
    InitializeComponent();
    LEDPanel.ItemsSource = bitArray;
}
于 2012-12-21T00:07:29.643 に答える
1

対象となる概念は、INotifyPropertyChanges(.net 4.5(他のバージョンでは最小限の変更ですが、同じ概念))、ItemsControl、そして最後にスタイルトリガーです。

INotifyPropertyChanges

私の最初のステップは、メインウィンドウにINotifyPropertyChangesを配置して、変更をWPFコントロールに自動的に通知することです。ビット配列をリストに変換し、必要に応じて(おそらくタイマーで?)ドロップするだけです。いくつあるかは関係ありません...コントロールが拡張されます。

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&Style Triggers

次に、WPF xamlで、boolのリストにバインドし、アイテムテンプレートを使用します(見つかった各データアイテムの一般的なミニビューを考えてください)。そのテンプレート内で、ブール値の状態に応じて赤または緑の色を表示します。

目標値に合わせたスタイルトリガーを設定するため、コンバーターは必要ありません。Textblocksのテキストが「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-21T00:44:58.410 に答える
0

これを試して。これは明らかに単なる例です。WPF の機能を使用し、.a とは異なるコントロールを使用することをお勧めします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 array
于 2012-12-20T23:33:25.137 に答える