gpt4 book ai didi

c# - ViewModel 的暴露数据取决于 View 的大小

转载 作者:行者123 更新时间:2023-11-30 12:45:14 25 4
gpt4 key购买 nike

背景

我是一名初学者 WPF 开发人员。作为学习练习,我尝试使用 WPF 和 MVVM 模式重新创建 Visual Studio 的内存窗口。对于那些不熟悉这个窗口的人。

实现纲要

为简单起见,我们假设内存是只读的并且不会改变。根据 MVVM 模式,我们定义了以下实体:

模型

模型 是一个简单的对象,包含 2 个属性:

  • long Address
  • 数据驻留在内存中的地址
  • byte[] Data

  • 模型 表示在定义的内存地址 ( Data) 处的字节序列 ( Address)。

    View 模型

    ViewModel 模型 作为输入并公开以下属性:
  • string Addresses
  • 一个 string,表示在同一行上显示的字节的地址。引用 Background 部分中的图片,Addresses string 包含第一列的内容,即:
    string Addresses = "0x022699B0" + '\n' +
    "0x022699C8" + '\n' +
    "0x022699E0" + '\n' +
    ...
  • string HexBytes
  • 模型 Data 的十六进制表示。引用 Background 部分中的图片,HexBytes string 包含第二列的内容,即:
    string HexBytes = "c0 ac 45 68 06 ..."
  • string ASCIIBytes
  • 模型 Data 的 ASCII 表示。引用 Background 部分中的图片,ASCIIBytes string包含第三列的内容,即:
    string ASCIIBytes = "A.Ch....9.1.1.1.2.5 ..."

  • 总而言之, ViewModel View 友好格式公开给定我的 模型 的数据。

    看法

    View 可能最容易通过 XAML 代码片段来描述:
    <UserControl x:Class="HexEditor.HexView"
    xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:z="clr-namespace:HexEditor">

    <UserControl.DataContext>
    <z:MemoryViewModel/>
    </UserControl.DataContext>

    <Grid>
    <Grid.RowDefinitions>
    <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition Width="3*"/>
    <ColumnDefinition Width="1*"/>
    </Grid.ColumnDefinitions>

    <TextBox Grid.Column="0" IsReadOnly="True" Cursor="Arrow" FontFamily="Consolas" Text="{Binding Addresses, Mode=OneWay}"/>
    <TextBox Grid.Column="1" IsReadOnly="True" TextWrapping="Wrap" Cursor="Arrow" FontFamily="Consolas" Text="{Binding HexBytes, Mode=OneWay}" />
    <TextBox Grid.Column="2" IsReadOnly="True" TextWrapping="Wrap" Cursor="Arrow" FontFamily="Consolas" Text="{Binding ASCIIBytes, Mode=OneWay}" />
    </Grid>

    请注意 TextWrapping 属性已在第二列和第三列上设置。这允许我们根据窗口的大小显示每行可变数量的字节。

    问题

    我遇到的问题是 ViewModel 必须公开的属性取决于 View 的大小。在 MVVM 模式中, ViewModel 应该独立于 View 。这对 HexBytesASCIIBytes 来说不是问题,因为它们是从 模型 生成的。问题是如何生成 Addresses ?要生成这个 string,我必须知道每行将显示的字符数(以便我可以计算下一行第一个字节的正确地址)。不幸的是,这只有 View 知道,因为它取决于 View 的大小。

    建议的解决方案

    我解决这个问题的尝试是在 View 代码隐藏中捕获 SizeChanged 事件,并使用 TextBox.GetLineLength 方法通知 ViewModel 一行可以容纳多少字节。 ViewModel 然后可以使用这个值来生成正确的 Addresses 属性。

    讨论

    关于我提出的解决方案,我有两个问题:
  • 是否有更优雅的方式通知 ViewModel 可以显示在第二个 TextBox 的 1 行上的字符数?
  • 我是否使用了正确的控件和更重要的正确方法来获得最终结果(即重新创建 Visual Studio 的内存窗口)?

  • 非常感谢您的任何意见或意见。

    最佳答案

    Is there a more elegant way of informing the ViewModel on the number of characters that can be displayed on 1 line



    我认为你的方法是最好的。您想到的结果——带有推断列标题的可变列宽——意味着 View 模型对 View 的依赖。 (一些 MVVM 方法使用某种“消息”框架(例如,事件聚合器)在 View 和 View 模型之间进行通信,但这只是让 View 直接调用 View 模型上的方法的更正式的方式。)此外,在任何情况下,您都需要处理 SizeChanged 事件,以便在每次调整大小时重新生成列标题。

    Am I using the correct Controls and the correct approach more importantly to get to my end result



    看起来不错。您可能会考虑将 ObservableCollection<string>ItemsControlListBox 一起使用(而不是带有换行符的扁平字符串)。这将允许您更好地控制 UI,启用诸如突出显示/选择单个地址之类的功能;地址/字节的同步滚动;和虚拟化面板来处理更大的数据集,而无需打磨 UI。

    关于c# - ViewModel 的暴露数据取决于 View 的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25391514/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com