2011-01-04 13 views
2

私はユーザーが複数のオン/オフシーケンスのシーケンスを選択できるアプリケーションに取り組んでいます。シーケンスは常にオン期間から始まり、さまざまな長さを持つことができます(ただし、常にオン/オフペアになります)。WPFシーケンスをグラフィカルに表示するためのヒント

var sequences = new [] 
{ 
    new int[] { 10, 15 },  // 10 ms on, 15 ms off 
    new int[] { 15, 10, 5, 10 } // 15 ms on, 10 ms off, 5 ms on, 10 ms off 
}; 

シーケンスの最大持続時間は10秒であり、繰り返されます。 1つの特別なシーケンスでは、オン/オフの持続時間は定義されていません。常にオンです(ただし、それを{1,0}などに変更することもできます)。

数字を画面に表示する代わりに、完全な10秒間の表示(短いシーケンスの繰り返し)を少し表示して、パターンを比較できるようにしたいと思います。これらは、ウィンドウでサイズ変更されるコンボボックスに表示されます。私は(唯一の特別な値の場合)の値コンバーターを使用する必要がありますと仮定しますが、確信がもてない、それ以上の例次のようになります(Xはバックグラウンドで満たされている場合)

xx xx xx xx xx xx xx... 
xxx x xxx x xxx x xxx x ... 

用グラフを作成する最も簡単な方法は、特にサイズ変更の要件と短いシーケンスを繰り返すことです。キャンバス、他に何か?

大変ありがとうございます。

答えて

1

私は、この基本的なアプローチに従うでしょう:

  1. は期間があるかどうかを指定したクラスとの時間の各チャンクをコードする、各シーケンスを取り、完全な10秒にシーケンスを繰り返し、値コンバータを書きます'オン'と継続時間。

  2. 各シーケンスについて、ItemsControlのItemsSourceにバインドします。 ItemsPanelの場合は、水平方向のStackPanelを使用します。 ItemTemplateの場合は、矩形、または他のどのようなビジュアルでも時間の塊にしたい場合は、幅を期間にバインドします。オン/オフ状態を簡単に視覚化できるように、便利な 'IsOn'プロパティも含まれています。この時点でWidthをスケールすることについて心配しないでください。

  3. ItemsControlをViewBoxに配置します。これは、親コンテナにストレッチすることができます。今度は、持続時間とスケールの正確な比率をサイズで表示するビジュアルがあります。


ここでは最低限の実装(なしエラー処理やかなりそれを作るしようとする)です:

UDPATE:適切に10秒でシーケンスを繰り返す切り捨てていなかったバグを修正しました。

using System; 
using System.Collections.Generic; 
using System.Globalization; 
using System.Windows; 
using System.Windows.Data; 

namespace TestWpf 
{ 
    public class SeqSegment 
    { 
     public bool IsOn { get; set; } 
     public int Duration { get; set; } 
    } 

    public class SeqConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      var result = new List<SeqSegment>(); 
      var seq = (int[]) value; 
      int time = 0; 
      int i = 0; 
      bool isOn = true; 
      while (time < 10000) 
      { 
       result.Add(new SeqSegment { Duration = Math.Min(seq[i], 10000 - time), IsOn = isOn }); 
       isOn = !isOn; 
       time += seq[i]; 
       i++; 
       if (i >= seq.Length) 
        i = 0; 
      } 

      return result; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotSupportedException(); 
     } 
    } 

    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public IEnumerable<int[]> TestSequences 
     { 
      get 
      { 
       yield return new[] {10, 5000, 10, 8}; 
       yield return new[] {500, 5000}; 
       yield return new[] {50, 400, 30, 10}; 
      } 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = this; 
     } 
    } 
} 

XAML:

<Window x:Class="TestWpf.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:TestWpf="clr-namespace:TestWpf" Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <TestWpf:SeqConverter x:Key="SeqConverter"/> 
     <DataTemplate x:Key="SeqSegTemplate"> 
      <Rectangle x:Name="Rect" Width="{Binding Duration}" Fill="Blue"/> 
      <DataTemplate.Triggers> 
       <DataTrigger Binding="{Binding IsOn}" Value="True"> 
        <Setter TargetName="Rect" Property="Fill" Value="Green"/> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </DataTemplate> 
     <DataTemplate x:Key="SeqTemplate"> 
      <Viewbox Height="50" Stretch="Fill"> 
       <ItemsControl ItemsSource="{Binding Converter={StaticResource SeqConverter}}" ItemTemplate="{StaticResource SeqSegTemplate}"> 
        <ItemsControl.ItemsPanel> 
         <ItemsPanelTemplate> 
          <StackPanel Orientation="Horizontal" Height="1"/> 
         </ItemsPanelTemplate> 
        </ItemsControl.ItemsPanel> 
       </ItemsControl> 
      </Viewbox> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <ItemsControl ItemsSource="{Binding TestSequences}" ItemTemplate="{StaticResource SeqTemplate}"/> 
    </Grid> 
</Window> 
+0

私が代わりにアイテムコントロールのコンボボックスを使用して、シーケンスの表示は一つのことを除いて、罰金です:代わりにコンテンツをスケーリングの、ビューボックスは成長します。私はWidths:Auto、Auto、*の3つの列を持つコンボボックステンプレートのグリッドを持っています。シーケンス(ビューボックス)は3列目に表示されますが、サイズは制限されません。 – Stefan

+0

@Stefan、正しいことですが、*列に配置すると、ViewBoxは拡大しようとします。ComboBoxドロップダウンはリストされたアイテムを収容するために拡大しようとするため、コンテンツに幅のレイアウト提案は提供されないため、固定幅を指定することはありません。幅を変更したい場合は、幅はどのように設定する必要がありますか? –

+0

コンボボックスはウィンドウの幅を変更します。ウィンドウのメイングリッドの*列にあります。私は、コンボボックスの最初の2つの列を自動サイズにし、グラフを残りのコンボボックスに追加します。コンボボックスのコンテナの動作を変更してレイアウトの提案を提供する方法はありませんか? – Stefan

関連する問題