2011-06-28 21 views
0

私のプログラムは、シリアル接続を介して火災警報パネルから入力を受け取り、それに基づいてリストを作成する必要があります。新しいデバイスがパネルから報告されると、その文が解析され、デバイスがデバイスリストに追加されます。WPF DataGridを動的に実装する

私のプログラムのその部分は、すべてうまく動作します。この問題は、火災警報装置のリストをユーザーに表示することです。

DataGridを使用してこれを行うことを望んでいます(より良い方法がない限り)が、私に関連するWPF DataGridsに関する多くの有用なドキュメントを見つけることができません。そこにあるもののほとんどは、データベースからのデータを表示しているようです。しかし私は、パネルが新しいデバイス記述を吐き出し、私のプログラムのデバイスリストが追加されるたびに更新する必要があります。

私はAutoGenerateColumnsをtrueに設定して、最初は自分のリストを表示することができます。しかし、私は列見出しをカスタマイズしたいと思います。また、リストが追加されたときにこれは更新されないので、私はそれを "リフレッシュ"する方法がわかりません。

AutoGenerateColumnsがfalseの場合、データは表示されません。プログラムが実行されると、私のリストの項目数に対応する正しい行数が表示されますが、データは表示されません。どのように/それぞれの列を対応するデバイスデータメンバーにリンクする必要があるのだろうか?

最後に、サイズ変更によってかなり見えるようにDataGridをフォーマットするにはどうすればよいですか?私は列の幅とすべてを設定することができますが、私が望むのは、列のいくつかは幅を固定し、残りの有効領域を埋めるために中央の列を展開することです。

これはWPFでの最初のスタブです。どんな助けでも大歓迎です!

答えて

3

個人的に私は非常にDataGridのを好まないように、それは動的なシナリオでデータグリッドを作成するのに役立ちます。はい、バインドするのが簡単ですし、組み込みのサイズ変更と並べ替えのオプションが用意されていますが、ObjectsControlほど柔軟ではありません。私自身を説明させてください。

私はItemsControlにObservableCollectionを設定する傾向があります。次に、ItemsControlにカスタムアイテムを表示する方法を伝えるためにDataTemplateを使用します。

MVVMを実行している場合、CustomObjectsはModelesオブジェクトにすることができます。 リストがObservableCollectionにバインドされている場合、追加されたアイテムと削除されたアイテムがリストに動的に表示されます。 列サイズでは、グリッドをGridColumnsの幅を一部の列の固定幅に、*を他の列の幅に指定することで、残りの領域を埋めることができます。

GridViewの代替方法 私はItemControlの周りにScrollViewerを使用しているので、ItemsControlが大きすぎる場合はスクロールすることができます。 ItemsControlのItemSourceはFireAlarmのObservableCollectionにバインドされています。 ItemsControlのWrapPanelには各DataTemplateが含まれます。それは(あなたがするかどうかの祖先)幅が

<ScrollViewer 
    Grid.Row="x" 
    Grid.Column="y" 
    VerticalScrollBarVisibility="Auto" 
    Margin="5"> 

    <ItemsControl 
    BorderBrush="DarkBlue" 
    BorderThickness="2" 
    ItemsSource="{Binding Path=FireAlarms}" 
    ItemTemplate="{StaticResource FireAlarmsTemplate}" 
    > 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel 
         Orientation="Horizontal" 
         Width="{Binding RelativeSource= 
          {RelativeSource FindAncestor, 
          AncestorType={x:Type ItemsControl}}, 
          Path=ActualWidth}" 
         > 
       </WrapPanel> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
    </ItemsControl> 
</ScrollViewer> 

[OK]をItemsControlには、あなたがたDataTemplateを必要としている彼の親にバインドされます。 DataTemplateは、ウィンドウのressourceまたはDataDictionnaryに配置できます。あなたはクラスを持って言うことができます:ここで

FireAlarm 
{ 
    Public String AlarmInfo1; 
    Public String AlarmInfo2; 
    Public String AlarmInfo3; 
} 

で始まるのに良いのDataTemplateのようになります。

<DataTemplate x:Key="FireAlarms"> 
    <Border 
     BorderBrush="SteelBlue" 
     Background="LightBlue" 
     BorderThickness="2" 
     Margin="10" 
     Padding="10"> 
     <StackPanel 
      Orientation="Vertical" 
      > 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition></RowDefinition> 
        <RowDefinition></RowDefinition> 
        <RowDefinition></RowDefinition> 
       </Grid.RowDefinitions> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition></ColumnDefinition> 
        <ColumnDefinition Width="5"></ColumnDefinition> 
        <ColumnDefinition></ColumnDefinition> 
       </Grid.ColumnDefinitions> 


       <Label 
        Grid.ColumnSpan="3" 
        Grid.Row="0" 
        Content="{Binding Path=AlarmName}" 
        Margin="5,-5,5,10" 
        FontWeight="Bold" 
        FontSize="16" 
        HorizontalContentAlignment="Center" 
        HorizontalAlignment="Center"> 
       </Label> 

       <TextBlock 
        Text="Alarm information 1" Grid.Row="1" Grid.Column="0" /> 
       <TextBox 
        Text="{Binding Path=AlarmInfo1}" 
        Grid.Column="2" 
        Grid.Row="1" 
        > 
       </TextBox> 

       <TextBlock 
        Text="Alarm information 2" Grid.Row="2" Grid.Column="0" /> 
       <TextBox 
        Text="{Binding Path=AlarmInfo2}" 
        Grid.Column="2" 
        Grid.Row="2" 
        > 
       </TextBox> 

       <TextBlock 
        Text="Alarm information 3" Grid.Row="3" Grid.Column="0" /> 
       <TextBox 
        Text="{Binding Path=AlarmInfo3}" 
        Grid.Column="2" 
        Grid.Row="3" 
        > 
       </TextBox> 
      </Grid> 
     </StackPanel> 
    </Border> 
</DataTemplate> 

[OK]を、私はこれがあなたのために便利であると思います。私のテンプレートは1アラームあたり1平方メートルを生成します。 GridViewのようなテーブルに入れたいのであれば、縦向きのスタックパネルを使ってこれを修正し、変数//可変な列幅のグリッドを使うことができますが、何か有用なものを求めたので、何かと一緒に楽しい!

お楽しみください!

+0

WPFのすべては、少なくとも10倍以上複雑になっているようです。 –

1

これは多くの質問が1つに巻き込まれています。質問をする前に、もう少し背景研究をすることをお勧めします。私はあなた、私はしばらく前にWPFのDataGridについて書いたこのCodeProjectの記事を読むことをお勧めします:

http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx

それはあなたのためにあなたの質問のほとんどにお答えします

0

MVVMパターンを見ると、このアプリケーションを作成するときに大きな助けになります。

あなたが望むのは、ViewModelのObservableCollectionです。このコレクションには、DataGridのItemsSourceプロパティをバインドします。次に、列をさまざまなプロパティにバインドして表示させます。このObservableCollectionに項目が追加されるたびに、フロントエンドが自動的に更新されます。

列を自動サイズにするには、幅= "*"を設定します。あなたはあなたの努力を続けている。ここ

は、各問題に対して個別の質問を投稿し、MVVM

<DataGrid ItemsSource="{Binding FireAlarmCollection}" SelectedItem="{Binding SelectedFireAlarm, Mode=TwoWay}" AutoGenerateColumns="True" CanUserSortColumns="True" HorizontalScrollBarVisibility="Visible" CanUserResizeColumns="True"> 
</DataGrid> 

とデータグリッドのサンプルです。

1

ダイナミックグリッド(設計時に列の数とデザインが不明であることを意味します)の場合、バインディングを使用してコードビハインドを実行します。私は一般的にMVVMパターンを使用します(これに慣れていない場合は、WPFで作業するときのパターンなので、実際に読み込むことをお勧めします)。

1)あなたがここに(もちろんfalseに列を自動生成し、グリッドに名前を付ける設定する必要がmyDataGrid)

GridViewDataColumn newColumn= new GridViewDataColumn(); 
myDataGrid.Columns.Add(newColumn) 

これはあなたのグリッドに列を追加します。これで列が空になります。今はデータにデータをどのように埋め込むかによって異なります。あなたが項目上の既知のプロパティにバインドする場合は、操作を行います。

newColumn.Binding = new Binding("knownPropertyName"); 

しかしほとんどの場合、あなたは、プロパティ名を知っているし、コレクション内の要素に結合しません。 それ以上のものを望みます:

myDoubleCollection.Add(someDoubleValue); //do this for each item in the itemssource of the grid 
    int index=myDoubleCollection.Count-1; 
    newColumn.Binding = new Binding(string.Format("myDoubleCollection[{0}]",index)); 

これも同じです。 念頭に置くべきもう一つのことは、列の削除です。これには余分な作業が必要です。

関連する問題