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

7fhtutme  于 2022-11-30  发布在  Windows
关注(0)|答案(1)|浏览(309)

我需要编写一个Windows窗体,用户可以在其中查看许多按“客户”分组的“合同”。每个客户必须是一个展开-折叠面板,客户的合同必须在相应的面板内。
我已经尝试过很棒的ExpandCollapsePanel,但是当客户数量很大时,面板不会自动滚动,即使将 AutoScroll 属性设置为 true
有没有人知道一些其他的替代方案?请记住,面板必须动态创建,因为有许多客户和许多合同属于每个客户。

5m1hhzi4

5m1hhzi41#

好的,我已经创建了一个使用ElementHost来托管WPF UserControl的示例,它看起来像这样:

我已经上传了完整的源代码Here,但无论如何这些都是最相关的部分:
表格1:

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());
    }
}
  • (为简洁起见,省略了设计器代码)*

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>

代码隐藏:

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

视图模型:

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

    public void LoadCustomers(List<Customer> customers)
    {
        Customers = customers;
        OnPropertyChanged("Customers");
    }
}
  • 请注意,这个简单的、不到100行代码、20分钟的WPF示例比您希望在winforms中实现的任何功能都要好,而且不需要任何"所有者绘制," "P/调用"(不管这意味着什么)或可怕的庞大代码背后的东西。并不强迫你花很多钱在第三方组件,如devexpress或telerik。这就是为什么WPF是所有. Net Windows桌面应用程序开发的最佳选择,无论它是简单的Hello World类型的东西。
  • 我使用一个ItemsControl来托管Customer项,并在其中使用一个带有自定义DataTemplate的ListBox来显示Contract项。
  • 两个ItemsControl(外部和内部)都是Virtualized,即使有200,000个项目,也可以实现即时响应。
  • 注意,没有一行代码与UserControl的UI元素交互,所有内容都在XAML中定义,并通过DataBinding填充数据。这实现了大量的可伸缩性和可维护性,因为UI与应用程序逻辑/业务逻辑完全分离。这就是WPF的方式。
  • Form代码(初始化代码除外)只与ViewModel交互,不需要与WPF视图交互。
  • 当从winforms升级到WPF时,您确实需要接受The WPF Mentality,也就是说,如前所述,您几乎从不在过程代码中操作UI元素,或者使用太多的代码,而是使用DataBinding处理所有内容并接受The MVVM Pattern
      • WPF Rocks**。下载链接的源代码并亲自查看结果。
  • 如果你需要进一步的帮助,请告诉我。

相关问题