ListBoxItem 中的复杂 UI

10

在WPF中,我可以通过为ListBox提供一个ItemTemplate来将任何UI添加到ListBoxItem中:

在WPF中,我可以通过为ListBox提供一个ItemTemplate来将任何UI添加到ListBoxItem中:

 <ListBox ItemsSource="{Binding}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="Gray" CornerRadius="8" Padding="4,0,4,0">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition/>
                            </Grid.ColumnDefinitions>

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

                            <CheckBox Grid.Column="1" Content="Is Active Customer" IsChecked="{Binding IsActive}"/>

                            <Label Content="Id:" Grid.Row="1" HorizontalAlignment="Right"/>
                            <Label Content="Name:" Grid.Row="2" HorizontalAlignment="Right"/>

                            <TextBox Text="{Binding Id}" Grid.Row="1" Grid.Column="1"/>
                            <TextBox Text="{Binding Name}" Grid.Row="2" Grid.Column="1"/>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

结果如下:

enter image description here

在Windows Forms中有没有实现相同效果的方法?

编辑:

1 - 在Windows Forms中有没有一种方式可以实现同样的功能,同时保持视图应用程序逻辑之间的关注点分离,以便如果我以后想完全重新定义视图,我不必重构整个应用程序?

2 - WinForms是否支持数据绑定,以便我可以将我的每个ListBoxItems绑定到一个复杂的实体,最终包括从模型数据到UI数据的中间类型转换,并且不必编写大量样板代码来填充视图,然后将UI值传回模型以保存?

3 - 如果我想以某种方式引入动画,使当前的SelectedItem能够扩展自身并进入某种“行详细信息”模式,您可以看到大量其他信息怎么办?

4 - WinForms是否支持UI虚拟化,以便如果我有100万个项目,它不需要花费一生时间来加载UI,并仅呈现屏幕上可见的内容?

5 - 比如我想把复杂的图形引入到方程式中。 WinForms是否具有渲染硬件加速的功能?

6 - 如何使所有这些分辨率无关,以便ListBox及其所有内容可以拉伸到可用窗口大小,以利用更大的屏幕,同时与较小的屏幕兼容?

7 - 建议使用ListView控件而不是常规的ListBoxListView是否提供将任何UI添加到其中的功能?例如,我可以为每个项目添加视频吗?或者包含保存和编辑按钮的复杂主/细节模板?

8 - WinForms是否提供一致且足够的文档模型,以支持创建高保真度的所见即所得文档和其他类型的丰富内容?


@HighCore 是的,这是可能的,但您必须编写一个UserControl,该UserControl将对象作为DataContext获取。 - Knerd
@Knerd,你能详细解释一下吗? - Federico Berasategui
4
Winforms并非为您尝试的功能而设计。如果您想要WPF的功能,为什么不使用WPF呢? - Sam Axe
@HighCore 哦,你想在 WF 中做这个?那不是我的领域。我可以向你展示如何在 WPF 中完成... 在 WF 中,也许可以使用一个 UserControl,它扩展了 ListBox 和 ListBoxItem。 - Knerd
3
哎呀,我讨厌WinForms...ListView本身是不会帮助你的;如果我没记错的话,它不支持任何复杂的绑定。我依稀记得可以使用各种属性(如Bindable)和辅助工具(如TypeDescriptor)将一些东西拼凑在一起,但我已经很久没有在那个领域里折腾了。 - JerKimball
显示剩余3条评论
2个回答

21
为了回答这个总体问题——如何在WinForms中实现此功能——我建议以下操作:
  1. 在你的WinForms应用程序中使用一个WPF ListBox,包装在一个ElementHost中。这种方法有其自身的问题,但我认为这是获得所需效果最清晰的方式。

    如果这样做不适合您的需求,则

  2. 使用第三方控件套件,其中包含支持此功能的组件(Infragistics和DevExpress都可以)。

  3. 创建自己的派生ListBox控件,覆盖绘制等内容以呈现所需的内容。

针对您的各个问题:
  1. 有没有办法在 Windows Forms 中实现同样的功能,同时保持视图和应用程序逻辑之间的关注点分离,以便如果我以后想完全重新定义视图,就不必重构整个应用程序?
    过去,我曾经使用 Windows Forms 的 MVP(模型-视图-表示器)范例。它可以将视图与业务逻辑分开,尽管不如 WPF 的 MVVM 方法干净利落。我能给出的最好建议是:不要将业务逻辑放在事件处理程序中。

  2. Winforms 是否支持数据绑定,以使我每个 ListBoxItems 都可以绑定到一个复杂的 Entity,最终包括从模型数据到 UI 数据的中间类型转换,并且不需要编写大量样板代码来填充视图,然后将 UI 值传回模型以保存?
    不支持。Windows Forms 数据绑定不支持复杂数据绑定。您可以通过 ICustomTypeDescriptor 或 IBindingSource 自行实现某些东西,它可以接受复杂路径并为绑定目的进行评估...但没有任何现成的东西可供使用。

  3. 如果我想以一种方式引入 动画,使当前的 SelectedItem 以动画方式展开为某种“行详细信息”模式,您可以在其中查看大量其他信息?
    您必须自己编写 Windows Forms ListBox 和 ListBoxItems,并覆盖绘图操作。

  4. Winforms 是否支持 UI 虚拟化,以便如果我有 100 万个项目,它不会花费一生时间来加载 UI,并仅呈现屏幕上可见的内容?
    没有现成的支持,但某些第三方控件套件具有支持虚拟化类型的组件...但与 WPF 完全不同。

  5. 假设我想引入复杂的图形。 Winforms 渲染是否硬件加速?
    Windows Forms 基于 GDI+。GDI+ 不支持硬件加速:Windows Forms very slow under Windows7?

  6. 如何使所有这些 分辨率无关,使 ListBox 及其所有内容拉伸到可用窗口大小,以利用更大的屏幕,同时保持与较小屏幕的兼容性?
    您可以使用 Windows Forms 中的 Docking 和 Anchoring 来实现此目的。或者,您可以添加自定义事件处理程序,根据分辨率和窗口大小执行适当的布局调整。

  7. 建议使用 ListView 控件而不是常规的 ListBoxListView 是否提供将任何 UI 添加到其中的功能?例如,我可以为每个项目添加视频吗?或具有保存和编辑按钮的复杂主/细节模板?
    这是简化...但 ListView 只是支持多种视图类型的 ListBox。它在数据绑定方面也更加受限。http://blog.gfader.com/2008/09/winforms-listbox-vs-listview.html

  8. Winforms 是否提供一致且充足的[文档模型][2],以

    简而言之,如果这是一个可接受的解决方案,我会将你的WPF ListView包装在ElementHost中,然后结束。

3
我想在第8点上补充一下:听起来@HighCore对Winforms的思考方式与其设计非常不同。它并不是以文档为中心的模型。虽然它已经有了很大的发展,但Winforms实际上并没有太大的区别,就像VB6一样。越早接受它的本质,就越容易使用(或拒绝)。 - Chris Pfohl
1
我很欣赏你在这里回答了所有8-9个问题,为你的努力点赞。然而,在一个好的回答中还有一些小问题。首先,在你的第三个问题上,你实际上不需要自己编写ListBoxItems。从ListBox继承,使其拥有者绘制,并编写自定义绘制代码就足够了,而且并不难。其次,你的第四个问题只是部分正确的。你说WinForms没有公开Win32 ListBox控件的虚拟模式,但是一些P/Invoke可以轻松解决这个问题。你需要添加的样式标志是“LBS_NODATA”。 - Cody Gray
2
如果您已经切换到ListView控件(与您链接的文章作者的观点相反,我实际上建议这样做),您可以简单地设置其VirtualMode属性,该属性正是为此目的而设计的。像ListBox一样,ListViews也支持自绘,因此它们是您想要多么可定制的。 - Cody Gray
9
@HighCore请考虑不回答/评论关于特定WinForms技术的问题。这不是分享你对该技术负面意见的场所。我同意你的观点,但这不是正确分享观点的地方。 - Andrew Barber

1
我们通过在可滚动面板中使用用户控件来实现这一点。 准备一个包含所有编辑控件的用户控件。 将它们添加到一个可滚动的面板中,其中的dock属性设置为Top。 通过监视所添加的用户控件项上的焦点和单击事件来实现项目选择行为。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接