首页 > 解决方案 > 将一个 WPF ListView 的项目与相对于另一个 ListView 中项目的最终布局的位置对齐

问题描述

根据评论,我想了一种方法来简化我的问题:嵌套在右侧列中的用户控件内的任意点将在布局和渲染后最终到达某个最终位置。我想找出那个点是什么,并调整左列上元素的高度,使其在那个 Y 坐标上结束。我想对所有盒子重复这个过程。

我制作了一个 WPF 窗口来显示解码的串行数据。我有一个带有字节块的左侧列,以及一个带有位字段块的右侧列。位字段可以是 1 到 16 位长,并且不一定与字节边界对齐。但是我希望字节列和位字段列保持同步。

我已经解决了将它们一起滚动的问题。我将两个列表视图放在一个滚动面板中以达到我想要的效果。

我需要帮助的任务是计算分配每个左侧(字节)块的高度,以便字节块之间的转换与适当的位(第一个红色箭头)对齐,从而使总长度正确(第二个红色箭头)。(注意:我随机选择了数字,但目的是右侧列显示左侧列的字节中的位 - 相同的数据以不同的方式显示该数据。这就是我希望列对齐的原因。 )

模拟两列布局。

它不是一个简单的数学计算的原因是块之间的边界占用空间,因此具有许多小位字段的部分将占用更多的垂直空间,而不是在较少字段中合并所有位的部分。我能够用复杂的代码来大致对齐它并计算它scale*num_bits + offset*num_transitions,但没有值scaleoffset(由反复试验确定)使它在所有情况下都对齐,并且对位字段框数据模板的任何调整都会需要找到新的scaleoffset常数。

这是窗口的实际数据绑定代码。 {Binding Height}是字节框的计算高度。

<ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="64"></ColumnDefinition>
            <ColumnDefinition Width="2*"></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <ListView Grid.Column="0" ItemsSource="{Binding SerialDataBytes}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="1" CornerRadius="8" Height="{Binding Height}" Width="52" Margin="1,1,1,1">
                        <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding Value}" />
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <local:BitDescriptionRow DataContext="{Binding SerialDataFields}" Grid.Column="1">
        </local:BitDescriptionRow>
    </Grid>
</ScrollViewer>

这是右侧列中用户控件的代码。{Binding Bits}{Binding BorderThickness}在每八位之后生成带有粗体分隔符的 1 和 0 的垂直列表。 {Binding Height}根据位数设置用户控件内容的高度。

    <ListView ItemsSource="{Binding}">
        <ListView.ItemTemplate >
            <DataTemplate>
            <Border BorderBrush="Black" BorderThickness="1" CornerRadius="8" Padding="4,4,4,4" Margin="1,1,1,1">
                <StackPanel Orientation="Horizontal" Height="{Binding Height}">
                    <ListView VerticalAlignment="Center" VerticalContentAlignment="Center" BorderThickness="0" ItemsSource="{Binding Bits}">
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <Border BorderThickness="{Binding BorderThickness}" BorderBrush="Black">
                                        <TextBlock Height="16" Text="{Binding Value}" />
                                    </Border>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                    </ListView>
                    <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding FieldValue}" Margin="4,4,4,4" />
                    <TextBlock Width="180" Height="auto" TextWrapping="Wrap" Text="{Binding Description}" />
                </StackPanel>
            </Border>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

理想情况下,我认为如果字节框以某种方式动态(布局时间)同步,则最好是在示例模型中红色箭头所在的位置。如果这需要两步布局(闪烁)也没关系。在真实(非模拟)版本中,我使用 MVVM 和数据绑定。字节块的高度是一个数据绑定属性,所以我设想通过数据绑定进入视图模型的位域的布局高度/布局位置。

我出现的示例都涉及直接迭代 UIElements,我愿意接受这是更好的方法。但是如果我走那条路,我怎么知道哪个 UIElement 与哪个视图模型一起使用,因为它是通过数据绑定列表而不是静态布局动态的?

对预期评论的回答:

标签: c#wpfxamllayout

解决方案


推荐阅读