简体   繁体   English

Windows窗体/ C#中的动态折叠面板创建

[英]Dynamic Collapse-Panel creation in Windows Forms / C#

I need to write a Windows Form where the user can view many "contracts" grouped by "customer". 我需要编写一个Windows窗体,用户可以在其中查看按“客户”分组的许多“合同”。 Each customer must be a expand-collapse panel, and the contracts of the customer must be inside of the corresponding panel. 每个客户必须是一个展开-折叠面板,并且该客户的合同必须在相应面板内。

I already tried the great ExpandCollapsePanel , but when the number of customers is big then the panel doesn't autoscroll, even with the AutoScroll property set to true . 我已经尝试了出色的ExpandCollapsePanel ,但是当客户数量很大时,即使AutoScroll属性设置为true ,面板也不会自动滚动。

Does anybody know some other alternatives? 有人知道其他替代方法吗? Remember the panels must be dynamically created because there are many customers and many contracts belonging to each customers. 请记住,必须动态创建面板,因为有许多客户和许多合同属于每个客户。

Thank you! 谢谢!

Ok, I've created a sample using an ElementHost to host a WPF UserControl , it looks like this: 好的,我已经使用ElementHost创建了一个示例来托管WPF UserControl ,它看起来像这样:

在此处输入图片说明

I've uploaded the full source code Here , but anyways these are the most relevant parts: 我已经在此处上传了完整的源代码,但是无论如何,这些是最相关的部分:

Form1: Form1中:

public partial class Form1 : Form
{
    public CustomerContractsViewModel ContractsVM { get; set; }

    public Form1()
    {
        InitializeComponent();

        ContractsVM  = new CustomerContractsViewModel();

        var customercontractsview = new CustomerContractsView(){DataContext = ContractsVM};

        var elementHost = new ElementHost() { Dock = DockStyle.Fill };
        elementHost.Child = customercontractsview;

        panel1.Controls.Add(elementHost);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ContractsVM.LoadCustomers(DataSource.GetCustomers());
    }
}

(Designer code omitted for brevity) (为简洁起见,省略了设计师代码)

WPF View: WPF视图:

<UserControl x:Class="ElementHostSamples.CustomerContractsView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.Resources>
        <!-- This style is applied to all Label elements within the UserControl-->
        <Style TargetType="Label">
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="HorizontalAlignment" Value="Right"/>
        </Style>

        <!-- This DataTemplate will be used to render the Contract items-->
        <DataTemplate x:Key="ContractTemplate">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>

                <Label Grid.Row="0" Grid.Column="0" Content="Contract Date:"/>
                <Label Grid.Row="1" Grid.Column="0" Content="Amount:"/>

                <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding ContractDate, StringFormat='MM/dd/yyyy'}" VerticalAlignment="Center"/>
                <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Amount, StringFormat=C}" VerticalAlignment="Center"/>
            </Grid>
        </DataTemplate>

        <!-- This DataTemplate will be used to render the Customer Items -->
        <DataTemplate x:Key="CustomerTemplate">
            <Expander Header="{Binding Name}">
                <ListBox ItemsSource="{Binding Contracts}" ItemTemplate="{StaticResource ContractTemplate}">
                    <ListBox.Template>
                        <ControlTemplate TargetType="ListBox">
                            <ItemsPresenter/>
                        </ControlTemplate>
                    </ListBox.Template>
                </ListBox>
            </Expander>
        </DataTemplate>
    </UserControl.Resources>

    <ListBox ItemsSource="{Binding Customers}"
             ItemTemplate="{StaticResource CustomerTemplate}"/>
</UserControl>

Code Behind: 背后的代码:

public partial class CustomerContractsView : UserControl
{
    public CustomerContractsView()
    {
        InitializeComponent();
    }
}

ViewModel: 视图模型:

public class CustomerContractsViewModel:PropertyChangedBase
{
    public List<Customer> Customers { get; set; }

    public void LoadCustomers(List<Customer> customers)
    {
        Customers = customers;
        OnPropertyChanged("Customers");
    }
}
  • Notice how this simple, less than 100 lines of code, 20-minute WPF sample is better than anything you can ever hope to achieve in winforms, and doesn't need any "owner draw", "P/Invoke" (whatever that means) or horrendous gargantuan code behind stuff. 请注意,这个简单的,少于100行代码,20分钟的WPF示例比您希望在winforms中实现的任何示例都要好,并且不需要任何“所有者抽奖”,“ P /调用”(无论这意味着什么)。 )或东西后面的巨大代码。 And does not force you to spend lots of money in third party components such as DevExpress or Telerik. 并且不强迫您在第三方组件(例如DevExpress或Telerik)上花费很多钱。 This is why WPF is the best option for ALL .Net Windows Desktop application development, regardless if it's a simple Hello World type of stuff. 这就是WPF是所有.Net Windows桌面应用程序开发的最佳选择的原因,无论它是简单的Hello World类型的东西。

  • I'm using an ItemsControl to host the Customer items, and inside these I'm using a ListBox with a custom DataTemplate to show the Contract items. 我正在使用ItemsControl托管Customer项目,并且在其中使用带有自定义DataTemplate的ListBox来显示Contract项目。

  • Both ItemsControl (outer and inner) are Virtualized to enable an immediate response time, even with 200,000 items. ItemsControl(外部和内部)都已虚拟化 ,即使有200,000个项目,也能立即响应。

  • Notice that there's not a single line of code that interacts with the UserControls' UI Elements, Everything is defined in XAML and populated with data via DataBinding . 请注意,没有一行代码与UserControls的UI元素进行交互,所有内容都在XAML中定义,并通过DataBinding填充了数据。 This enables a great amount of scalability and maintainability because the UI is completely decoupled from the application logic / business logic. 由于UI与应用程序逻辑/业务逻辑完全脱钩,因此可以实现大量的可伸缩性和可维护性。 That's the WPF way. 这就是WPF方式。

  • The Form code (except for the initialization code) only interacts with the ViewModel , and has no need to interact with the WPF View. Form代码(初始化代码除外)仅与ViewModel交互,而无需与WPF View交互。

  • When upgrading from winforms to WPF, you seriously need to embrace The WPF Mentality , which is, as mentioned before, you almost never manipulate UI elements in procedural code, or use too much code behind, but rather use DataBinding for everything and embrace The MVVM Pattern 从Winforms升级到WPF时,您非常需要拥抱WPF Mentality ,如前所述,您几乎从不操作程序代码中的UI元素,或在背后使用太多代码,而是对所有内容使用DataBinding并拥抱MVVM图案

  • WPF Rocks . WPF岩石 Download the linked source code and see the results for yourself. 下载链接的源代码,然后亲自查看结果。

  • Let me know if you need further help. 让我知道您是否需要进一步的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM