2011-06-28 156 views
0

我的程序需要通過串行連接從火災報警面板獲取輸入,並根據它填充列表。當從面板報告新設備時,該語句被解析並且設備被添加到設備列表中。動態填充WPF DataGrid

我的程序的一部分都工作正常和花花公子。現在的問題是向用戶顯示火警設備列表。

我希望能夠使用DataGrid來做到這一點(除非有更好的方法嗎?)但我無法找到很多有用的與WPF DataGrids相關的文檔。大部分外面的東西似乎都在顯示來自數據庫的數據。但是,每次面板吐出一個新的設備描述時都需要更新,並且我的程序中的設備列表被追加。

我看到我可以將AutoGenerateColumns設置爲true,並最初顯示我的列表就好。但是,我想自定義列標題。此外,這不會更新時附加列表,所以我不知道如何「刷新」它。

當AutoGenerateColumns爲false時,我不顯示數據。程序運行時,它會顯示與我列表中的項目數相對應的正確行數,但不會顯示數據。想知道如何/如果我需要鏈接每個列與其相應的設備數據成員?

最後,你如何格式化DataGrid以通過重新調整尺寸來美觀?我可以設置列的寬度和所有這些,但我想要的是一些列固定寬度,並擴大中間列以填補剩餘的可用區域。

這是我第一次嘗試WPF。任何幫助將不勝感激!

回答

3

本人來說我不喜歡的DataGrid得多。是的,它們更容易綁定,它們提供了內置的調整大小和排序選項,但它們不如在對象上具有良好DataTemplating的ItemsControl那麼靈活。讓我解釋一下自己。

我傾向於使用ObservableCollection填充ItemsControl。然後,我使用DataTemplate爲了告訴我的ItemsControl如何顯示我的自定義項目。

如果您在做MVVM,那麼您的CustomObjects可以是Modeles對象。 如果您的列表綁定到ObservableCollection,則添加和刪除的項目將動態顯示到您的列表中,這是我相信您嘗試執行的操作。 對於列大小,可以將指定GridColumns寬度的Grid指定爲某些列的固定寬度,對其他列指定*,以便填充剩餘空間。

這是GridView的替代方法 我在ItemControl上使用了一個ScrollViewer,所以如果ItemsControl太大,可以滾動它。 ItemsControl的ItemsSource綁定到你的FireAlarms的ObservableCollection。 ItemsControl中的WrapPanel將包含每個DataTemplate。這是(如果你願意或祖先)寬度爲綁定到他的父母是一個ItemsControl

<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> 

好吧,那麼你需要一個DataTemplate。你可以把DataTemplate放在你的Windows資源或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> 

好,我希望這是對你有用。我的模板每個鬧鐘將產生1平方。如果你想讓它像GridView一樣在Table中使用,你可以使用面向垂直的堆棧面板來修改它,並使用一個帶有變量//不變的列寬的網格,但是因爲你要求任何有用的東西,所以我很堅強,一些有趣的工作!

享受!

+0

WPF中的所有東西似乎至少比應該需要的複雜10倍。 –

0

看看MVVM模式,它會在你創建這個應用程序時有很大的幫助。

你想要的是ViewModel中的ObservableCollection。你將綁定數據網格的ItemsSource屬性到這個集合。然後讓您的列綁定到各種屬性以顯示它們。每當此ObservableCollection附加一個項目時,您的前端應自動更新。

要使列自動調整大小,請設置Width =「*」。

這裏有一個DataGrid的樣品與MVVM

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

當你繼續你的努力,每個問題後獨立的問題。

1

如果你是一個動態網格(意味着在設計時列的數量和設計是未知的),我用帶有綁定的代碼隱藏來完成它。我通常使用MVVM模式(如果您不熟悉這一點,我真的推薦閱讀它,因爲它是使用WPF時的模式)。

1)必須設置自動生成列假,當然,給電網一個名稱(這裏myDataGrid)

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

這將列添加到您的網格。現在該列將是空的。現在取決於你的數據如何填充數據。如果您綁定到一個已知財產上的項目,這樣做:

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

在大多數情況下,雖然,你不知道PROPERTYNAME並綁定到集合中的元素。 然後它想要更多:

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)); 

所以這也適用。 要記住的另一件事是刪除列。這需要一些額外的工作。