我正在尝试实现一个按钮,在某些项目的列表和平铺视图之间切换。后面的代码对于两者都是相同的,唯一的区别是显示的内容和属性的大小。目前我已经实现了列表视图,XAML看起来像这样:
<StackLayout>
<ListView x:Name="FilesListView"
ItemsSource="{Binding Files}"
ItemSelected="FileItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding IsFolder, Converter={StaticResource fileTypeToImageConverter}}" WidthRequest="40" HeightRequest="40" HorizontalOptions="Start"/>
<Label Grid.Column="1" Text="{Binding Path, Converter={StaticResource pathToFilenameConverter}}" HorizontalOptions="StartAndExpand"/>
<Label Grid.Column="2" Text="{Binding ModifiedDate, Converter={StaticResource dateConverter}}" HorizontalOptions="EndAndExpand"/>
<Label Grid.Column="3" Text="{Binding Size, Converter={StaticResource fileSizeConverter}}" HorizontalOptions="EndAndExpand"/>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
这是局部视图; FileBrowser控件嵌套在包含切换按钮的另一个堆栈布局中。该按钮在XAML中定义如下:
<ContentPage.ToolbarItems>
<ToolbarItem Text="Toggle View" Order="Primary" Icon="{Binding ViewIcon}" Command="{Binding ToggleViewCommand}"/>
</ContentPage.ToolbarItems>
其中ToggleViewCommand是:
protected void ToggleView()
{
FileBrowserControl.ToggleView();
ViewModel.ToggleViewIcon();
}
我需要帮助找出如何实施FileBrowserControl.ToggleView();
。我需要使用不同的XAML片段(表示平铺视图)动态交换网格XAML,或者在代码中更新网格。在定义tile视图的外观方面,第一个选项似乎更容易,但我不想通过创建FileBrowserXaml.xaml / FileBrowserXaml.xaml.cs来复制逻辑背后的代码,这些代码将具有逻辑相同的代码作为FileBrowser.xaml.cs。对于我想要做的事情,Xamarin的最佳做法是什么?
(作为旁注,这需要跨平台。)
更新:我决定尝试在代码中构建数据模板。到目前为止我有这个:
public void ToggleView()
{
DataTemplate itemTemplate;
if (_view == FileBrowserView.List)
{
itemTemplate = new DataTemplate(() =>
{
var cell = new ViewCell();
var grid = new Grid();
// Define columns
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
// Define rows
var image = new Image
{
WidthRequest = 40,
HeightRequest = 40,
HorizontalOptions = LayoutOptions.Start
};
image.SetBinding(Image.SourceProperty,
new Binding("IsFolder", BindingMode.Default, new FileTypeToImageValueConverter()));
grid.Children.Add(image, 0, 0);
var pathLabel = new Label {HorizontalOptions = LayoutOptions.StartAndExpand};
pathLabel.SetBinding(Label.TextProperty,
new Binding("Path", BindingMode.Default, new PathToFilenameValueConverter()));
grid.Children.Add(pathLabel, 1, 0);
var dateLabel = new Label { HorizontalOptions = LayoutOptions.StartAndExpand };
dateLabel.SetBinding(Label.TextProperty,
new Binding("ModifiedDate", BindingMode.Default, new DateTimeDisplayValueConverter()));
grid.Children.Add(dateLabel, 2, 0);
var sizeLabel = new Label { HorizontalOptions = LayoutOptions.EndAndExpand };
dateLabel.SetBinding(Label.TextProperty,
new Binding("Size", BindingMode.Default, new FileSizeDisplayValueConverter()));
grid.Children.Add(sizeLabel, 3, 0);
cell.View = grid;
return cell;
});
}
else
{
itemTemplate = new DataTemplate(() =>
{
var cell = new ViewCell();
var grid = new Grid();
// Define columns
grid.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(1, GridUnitType.Star)});
grid.ColumnDefinitions.Add(new ColumnDefinition {Width = new GridLength(1, GridUnitType.Star)});
// Define rows
var image = new Image
{
WidthRequest = 80,
HeightRequest = 80,
HorizontalOptions = LayoutOptions.Start
};
image.SetBinding(Image.SourceProperty,
new Binding("IsFolder", BindingMode.Default, new FileTypeToImageValueConverter()));
grid.Children.Add(image, 0, 0);
var pathLabel = new Label { HorizontalOptions = LayoutOptions.Start };
pathLabel.SetBinding(Label.TextProperty,
new Binding("Path", BindingMode.Default, new PathToFilenameValueConverter()));
grid.Children.Add(pathLabel, 0, 1);
cell.View = grid;
return cell;
});
}
FilesListView.ItemTemplate = itemTemplate;
}
我现在遇到的问题是,在平铺视图中,每个项目都在它自己的行上。我希望它们换行(路径应该在图像下面,但是每个路径/图像组合应该与下一个路径/图像组合并排,就像在Windows资源管理器或典型的应用程序启动器中一样)。构建数据模板以实现此目的的最佳方法是什么?网格是正确使用的模板还是有更好的模板?
答案 0 :(得分:0)
您是否尝试过使用ResourceDictionary和StaticResource?
我想你可以通过将ListView ItemTemplate设置为StaticResource然后让切换按钮切换出用于视图的那个来完成你想要的东西。
以下是我的想法:
<ContentPage>
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="TileViewTemplate">
<ViewCell>
<ViewCell.View>
<!-- the layout of your template here -->
</ViewCell.View>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="ListViewTemplate">
<ViewCell>
<ViewCell.View>
<!-- the layout of your template here -->
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
</ContentPage.Resources>
<ListView x:Name="FilesListView" ItemsSource="{Binding Files}"
ItemsSelected="FileItemSelected"
ItemTemplate="{StaticResource TileViewTemplate}"/>
</ContentPage>
然后,toggleview命令可以切换ItemTemplate属性。这样您就不必担心两个ListView - 它可以使XAML更易于管理。
只是一个想法,但ResourceDictionary确实对我有帮助。