我正在寻找以下情况的最佳实践。编写此方案只是为了以简化的方式说明问题。
假设我们有以下布局,用于存储地址。
尽管有些客户可能会认为,电子邮件比名称更重要,因此希望在名称之前显示它。一些客户可能需要更多空间来存放名称。一些客户之所以哭是因为他们根本不需要任何电话号码。
我的目标:用户应该能够决定自己的表单外观。
我想设置一个默认模板,该模板应适用于大多数客户。
我不想重塑轮子,那么有没有提供这种功能的库呢?
这样的功能可以是(在运行时):
重新排序控件(例如,通过拖放操作)
存储和加载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/