我正在寻找以下情况的最佳实践。编写此方案只是为了以简化的方式说明问题。

假设我们有以下布局,用于存储地址。


尽管有些客户可能会认为,电子邮件比名称更重要,因此希望在名称之前显示它。一些客户可能需要更多空间来存放名称。一些客户之所以哭是因为他们根本不需要任何电话号码。

我的目标:用户应该能够决定自己的表单外观。

我想设置一个默认模板,该模板应适用于大多数客户。

我不想重塑轮子,那么有没有提供这种功能的库呢?

这样的功能可以是(在运行时):


重新排序控件(例如,通过拖放操作)
存储和加载UI布局模板
设置控件可见/不可见
调整控件大小


如果没有,解决该问题的“最佳实践”将是什么?



如果必须重新发明轮子,最可能的解决方案是创建自己的XML,该XML将在运行时加载,然后设置行和列。
但是由于我对WPF还是很陌生,所以我不知道这是否是正确的解决方案。



最后,下面是上述示例的XAML:

<Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
                <RowDefinition Height="28" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Label Grid.Row="0" Grid.Column="0" Content="Name:"/>
            <Label Grid.Row="1" Grid.Column="0" Content="E-Mail:"/>
            <Label Grid.Row="2" Grid.Column="0" Content="Phone:"/>
            <Label Grid.Row="3" Grid.Column="0" Content="Address:"/>
            <TextBox Grid.Column="1" Grid.Row="0" Margin="3" />
            <TextBox Grid.Column="1" Grid.Row="1" Margin="3" />
            <TextBox Grid.Column="1" Grid.Row="2" Margin="3" />
            <TextBox Grid.Column="1" Grid.Row="3" Margin="3" />
            <Button Grid.Column="1" Grid.Row="4" HorizontalAlignment="Right" MinWidth="80" Margin="3" Content="OK" Click="Button_Click"  />
</Grid>

最佳答案

首先,最好在创建应用程序之前询问此问题。其次,我认为针对此任务动态创建View Perfect的方法是DataTemplate。您应该立即开始以MVVM样式开发应用程序,它对于动态View更合适。

DataTemplate中,关键角色扮演了DataTrigger。它们允许根据View中元素的值设置属性。例如,显示/隐藏按钮,设置高度/宽度等。

DataTemplate的示例:

<DataTemplate x:Key="MainView" DataType="{x:Type ViewModels:MainViewModel}">
    <Grid>
        <Button Name="UserButton"
                Content="Are you user?"
                Width="100"
                Height="30"
                HorizontalAlignment="Left"
                VerticalAlignment="Top"
                Command="{Binding UserButtonCommand}" />

        <Button Name="AdminButton"
                Content="Are you admin?"
                Width="100"
                Height="30"
                HorizontalAlignment="Right"
                VerticalAlignment="Top"
                Command="{Binding AdminButtonCommand}" />

        <StackPanel Name="MainViewPanel"
                    Tag="{Binding Path=MainModel.ContentType,
                                  Mode=TwoWay,
                                  UpdateSourceTrigger=PropertyChanged}">

            <TextBlock Name="TitleTextBlock"
                       Text="{Binding Path=MainModel.TitleText,
                                      Mode=TwoWay,
                                      UpdateSourceTrigger=PropertyChanged}"
                       FontSize="20"
                       HorizontalAlignment="Center"
                       VerticalAlignment="Center"
                       Visibility="Collapsed" />

            <TextBox Name="BannedTextBlock"
                     Text="{Binding Path=MainModel.BannedName,
                                    Mode=TwoWay,
                                    UpdateSourceTrigger=PropertyChanged}"
                     Visibility="Collapsed" />

            <Button Name="YesButton"
                    Content="{Binding Path=MainModel.ContentYesButton,
                                      Mode=TwoWay,
                                      UpdateSourceTrigger=PropertyChanged}"
                    Visibility="Collapsed" />

            <Button Name="NoButton"
                    Content="{Binding Path=MainModel.ContentNoButton,
                                      Mode=TwoWay,
                                      UpdateSourceTrigger=PropertyChanged}"
                    Visibility="Collapsed" />
        </StackPanel>
    </Grid>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding ElementName=MainViewPanel, Path=Tag}" Value="User">
            <Setter TargetName="TitleTextBlock" Property="Visibility" Value="Visible" />
            <Setter TargetName="YesButton" Property="Visibility" Value="Visible" />
        </DataTrigger>

        <DataTrigger Binding="{Binding ElementName=MainViewPanel, Path=Tag}" Value="Admin">
            <Setter TargetName="TitleTextBlock" Property="Visibility" Value="Visible" />
            <Setter TargetName="BannedTextBlock" Property="Visibility" Value="Visible" />
            <Setter TargetName="YesButton" Property="Visibility" Value="Visible" />
            <Setter TargetName="NoButton" Property="Visibility" Value="Visible" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>


给定两个按钮,一个用于用户,一个用于管理员。如果选择User,则向用户显示内容;如果选择Admin,则向管理员显示。 StackPanel的标记中指定的内容类型。请注意<DataTemplate.Triggers>部分。

完整的示例和示例说明在此处(他仍然很大):

Make (create) reusable dynamic Views

关于c# - 用户可定义的布局(在运行时),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22195623/

10-12 12:43
查看更多