我正在创建具有以下两个标签的网格对象的新实例。
<Grid x:Name="Grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70*"></ColumnDefinition>
<ColumnDefinition Width="30*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Label x:Name="Label1" Text="Label1" Grid.Column="0" Grid.Row="0"></Label>
<Label x:Name="Label2" Text="Label2" Grid.Column="1" Grid.Row="0"></Label>
</Grid>
我正在使用Activator.CreateInstance方法,如下所示:
Grid ClonedView =(Grid) Activator.CreateInstance(Grid.GetType());
foreach (PropertyInfo propertyInfo in Grid.GetType().GetProperties())
{
if (propertyInfo.CanRead && propertyInfo.CanWrite )
{
object PropertyValue = propertyInfo.GetValue(Grid, null);
propertyInfo.SetValue(ClonedView, PropertyValue);
}
}
当我在页面中使用此ClonedView时,它的Cloned Grid无法理解Label2应该出现在网格的第二列中。我对此进行了大量研究,但找不到任何解决方案。请让我知道是否有人可以解决。
谢谢
答案 0 :(得分:1)
您以这种方式思考的方式,对我来说就像JavaScript。您想通过复制所有属性来创建深层副本。但是,对于这样的事情,Xamarin对象太复杂了(即使您能够进行深层复制,例如Bindings也不适用于简单复制)。
因此,与其制作单个Grid
对象并尝试创建它的副本,不如查看它的另一种方式是“我想定义一个模板,然后根据该模板创建多个实例”。为此,Xamarin具有DataTemplate
类,这使我们能够在xaml中执行以下操作:
<ContentPage>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="MyGridTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70*"></ColumnDefinition>
<ColumnDefinition Width="30*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Text="Label1" Grid.Column="0" Grid.Row="0"></Label>
<Label Text="Label2" Grid.Column="1" Grid.Row="0"></Label>
</Grid>
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<Button Text="Add Grid" Clicked="AddGridClicked">
</Button>
<StackLayout x:Name="GridHolder">
<StackLayout>
<ContentPage>
在后面的代码中,我们可以像这样实现AddGridClicked
:
private void AddGridClicked(object sender, EventArgs e)
{
var myGridTemplate = (DataTemplate) Resources["MyGridTemplate"];
GridHolder.Children.Add((View)myGridTemplate.CreateContent());
}
现在的缺点是,您需要定义一个DataTemplate
而不是仅指向一个对象并说要获得副本。还要记住,x:Name
中View
中的DataTemplate
不能用页面后面的代码来访问,但是具有良好的Xamarin设置是不必要的。这样做的好处是,它可以完成可能的绑定,因此您可以像这样在网格中定义Label
:
<Label Text="{Binding Name}" Grid.Column="0" Grid.Row="0"></Label>
然后,如果您将模板化的Grid
设为不同的BindingContext
,则可以为每个实例赋予不同的数据,以将不同的数据绑定到其视图。
希望这会有所帮助