【问题标题】:ItemsControl with row and column headers WPF带有行和列标题 WPF 的 ItemsControl
【发布时间】:2018-07-18 07:53:39
【问题描述】:

我需要将对象RegisterBean 的可更新列表ObservableCollection<RegisterBean> listOfRegisters 表示为具有行和列标题的矩阵对象包含3 个属性:

byte deviceAddress;
byte register;
byte[] data;

并且应该只显示一个属性数据。 预期结果类似于图像:

我使用通常的数据网格达到了这个结构,但问题是更新它,因为我使用了一个带有new DataTable() 作为返回值的转换器。这是不正确的,因为它会闪烁并重新渲染所有对象。

我昨天寻求帮助 here。这个解决方案正在奏效:

<ItemsControl ItemsSource="{Binding listOfRegisters}">
   <ItemsControl.ItemsPanel>
       <ItemsPanelTemplate>
           <UniformGrid Columns="16"/>
                </ItemsPanelTemplate>
           </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
           <DataTemplate>
               <TextBox Text="{Binding Data, Converter={StaticResource ByteToStringValueConverter}}"/>
          </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

但我不明白如何更改用户控件的结构并添加标题。使用itemscontrol 解决的结果:

谢谢!

更新: 标题应该是静态的,没有任何排序之类的东西

【问题讨论】:

  • ItemsControl 没有列。 GridView 确实(例如 ListView 使用它)。
  • 所以你有一个大部分工作的DataGrid 有一个小更新问题,而不是尝试修复更新问题,你决定将整个基础架构降级到ItemsControl,然后你想知道如何将ItemsControl 改进到表现得更像DataGrid
  • @grek40 你 100% 正确,但我觉得这是解决我问题的方法。如果您有任何建议 - 欢迎您:)
  • 您能否举一个RegisterBean 对象的具体示例,该对象具有deviceAddressregisterdata 的具体值(请多字节)并解释它将出现在哪一行/哪一列,将显示什么以及如何对其进行编辑?
  • @grek40 这是从0x000xFF 的设备寄存器的表示。长度可以是 1 或 2 个字节(取决于设备)。每个单元格显示RegisterBeanData 属性。例如:deviceAddress = 0x60, register 0x5A, data = { 0xFF }。 DeviceAddress 仅用于绑定所选项目并在以后使用它(我没有在这个具体视图上显示它)。寄存器值给了我具体 bean 在数据网格中的位置(0x5A 将在行0x5 和列A 的交点处)。数据应该像图片一样显示为单元格值。

标签: c# wpf mvvm binding


【解决方案1】:

我开始说可能,检查 DataGrid 出了什么问题会更好,并且没有必要重新编写控件,但是如果您仍然想使用 ItemsControl ...

假设您的 ViewModel 中有两个包含您的标题的集合(ColHeaders 和 RowHeaders),您可以添加另外两个包含标题的面板..

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="auto"/>
        <ColumnDefinition Width="auto"/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>

    <!-- Column Headers -->
    <ItemsControl Grid.Column="1" Grid.Row="0"  ItemsSource="{Binding ColHeaders}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}" Width="30" Height="30"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    <ItemsControl Grid.Row="1" Grid.Column="1" ItemsSource="{Binding listOfRegisters}">
       <ItemsControl.ItemsPanel>
           <ItemsPanelTemplate>
               <UniformGrid Columns="16"/>
                    </ItemsPanelTemplate>
               </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
               <DataTemplate>
                   <TextBox Text="{Binding Data, Converter={StaticResource ByteToStringValueConverter}}"/>
              </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

    <!-- RowHeaders -->
    <ItemsControl Grid.Column="0" Grid.Row="1" ItemsSource="{Binding RowHeaders}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding}" Width="30" Height="30"/>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

我还调整了 TextBlocks 和 TextBoxes 的大小以对齐所有内容。

【讨论】:

  • 我也更喜欢datagrid,也许以后我会尝试找到解决方案。谢谢!
【解决方案2】:

只需在其周围添加一个网格,如下所示:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <Grid Grid.Row="0" Grid.Column="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="Col 0"/>
        <Label Grid.Column="1" Content="Col 1"/>
        <Label Grid.Column="2" Content="Col 2"/>
    </Grid>
    <Grid Grid.Row="1" Grid.Column="0">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Label Grid.Row="0" Content="Row 0"/>
        <Label Grid.Row="1" Content="Row 1"/>
        <Label Grid.Row="2" Content="Row 2"/>
    </Grid>
    <UniformGrid Rows="3" Columns="3" Grid.Column="1" Grid.Row="1">
        <Button Content="00"/>
        <Button Content="01"/>
        <Button Content="02"/>
        <Button Content="10"/>
        <Button Content="11"/>
        <Button Content="12"/>
        <Button Content="20"/>
        <Button Content="21"/>
        <Button Content="22"/>
    </UniformGrid>
</Grid>

【讨论】:

  • 为什么投反对票?这在 UniformGrid 周围提供了漂亮的列和行标题...?
猜你喜欢
  • 2011-08-18
  • 1970-01-01
  • 2011-02-24
  • 1970-01-01
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 2011-01-02
  • 1970-01-01
相关资源
最近更新 更多