我的程序需要通过串行连接从火警面板获取输入,并根据它填充列表。从面板报告新设备时,将解析该语句,并将设备添加到设备列表中。
我程序的那部分都运行得很好,花花公子。现在的问题是向用户显示火警设备列表。
我希望使用DataGrid来实现这一点(除非有更好的方法吗?)但是我无法在与我相关的WPF DataGrids上找到很多有用的文档。大部分内容似乎都是从数据库中显示数据。但是,每当面板吐出新的设备描述并且附加了我的程序中的设备列表时,我需要更新。
我看到我可以将AutoGenerateColumns设置为true,并且最初显示我的列表就好了。但是,我想自定义列标题。当附加List时,这也不会更新,因此我不确定如何“刷新”它。
当AutoGenerateColumns为false时,我没有显示任何数据。程序运行时,它会显示与列表中项目数相对应的正确行数,但没有数据。想知道如何/如果我需要将每个列与其对应的设备数据成员链接?
最后,如何通过重新调整大小来格式化DataGrid?我可以设置列宽和所有这些,但我想要的是一些要固定宽度的列,以及要扩展以填充剩余可用区域的中间列。
这是我第一次尝试WPF。任何帮助将不胜感激!
答案 0 :(得分:3)
Personaly我不喜欢DataGrid。是的,它们更容易绑定,它们提供内置的调整大小和排序选项,但它们不像在对象上具有良好DataTemplating的ItemsControl那样灵活。让我解释一下自己。
我倾向于使用ObservableCollection填充我的ItemsControl。然后,我使用DataTemplate告诉我的ItemsControl如何显示我的自定义项目。
如果你在做MVVM,你的CustomObjects可以是Modeles对象。 如果您的列表绑定到ObservableCollection,则添加和删除的项目将动态显示在您的列表中,这是我相信您的尝试。 对于列大小,您可以将Grid指定GridColumns宽度设置为某些列的固定宽度,将*设置为其他列,以便填充剩余空间。
这是GridView的替代方案 我在ItemControl周围使用ScrollViewer,所以如果ItemsControl太大,你可以滚动它。 ItemsControl的ItemSource绑定到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的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>
好的,我希望这对你有用。我的模板将为每个警报生成1个方格。如果你宁愿把它放在像GridView一样的表中,你可以使用面向verticaly的堆栈面板修改它,并使用一个具有可变//不变列宽的网格,但是因为你要求任何有用的东西,我很难惹你一些有趣的事情!
享受!
答案 1 :(得分:1)
这就是很多问题!我建议你在提问之前先做一些背景研究。我建议您阅读我之前写的关于WPF DataGrid的这篇代码项目文章:
http://www.codeproject.com/KB/WPF/WPFDataGridExamples.aspx
它将为您回答大部分问题!
答案 2 :(得分:1)
一段时间后我写了一篇帖子Create DataGrid in WPF using code看看它,它会帮助你在像你这样的动态场景中创建数据网格
答案 3 :(得分: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));
所以这也有效。 要记住的另一件事是删除列。这需要一些额外的工作。
答案 4 :(得分: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>
在您继续努力的同时,针对每个问题发布单独的问题。