问题
Hello I have a repeating carousel I've copied for each deparment that I want to consolidate and make into a custom xaml view control. Here is the original carousel view I have copied several times in my page. I want to figure out how to clean this up with something externally from the page.
<StackLayout Padding="10">
<Label Text="Human Resources" FontSize="Large"
TextColor="#000000"></Label>
<CarouselView ItemsSource="{Binding HumanResourcesCollection}"
PeekAreaInsets="75"
IndicatorView="Indicator"
HeightRequest="275">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" ItemSpacing="10"></LinearItemsLayout>
</CarouselView.ItemsLayout>
<CarouselView.EmptyView>
<StackLayout>
<Label Text="No results for this department"
FontSize="Large"
HorizontalOptions="Fill"
HorizontalTextAlignment="Center"></Label>
<Label Text="Contact your manager for more information"
FontSize="Medium"
HorizontalOptions="Fill"
HorizontalTextAlignment="Center"></Label>
</StackLayout>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<helper:LayoutGradient StartColor="{StaticResource Secondary}"
EndColor="{StaticResource Secondary}"
OptionCorner="True"
RadiusCorner="25"
DirectionColor="False">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="OnDepartmentSelected></TapGestureRecognizer>
</Frame.GestureRecognizers>
<Frame.Content>
<Grid RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.Row="0" Aspect="AspectFit" Opacity=".35" VerticalOptions="End" HorizontalOptions="End">
<Image.Source>
<FontImageSource Size="148" Glyph="{Binding Comments}"
FontFamily="{DynamicResource FontIcons}"
Color="Blue"></FontImageSource>
</Image.Source>
</Image>
<StackLayout
Grid.Row="0" Grid.Column="0">
<Label Text="{Binding Title}" FontSize="Medium" FontAttributes="Bold"
></Label>
<Label Text="{Binding Version}" FontSize="Small"></Label>
</StackLayout>
</Grid>
</Frame.Content>
</helper:LayoutGradient>
<Label Padding="0, 10, 0, 10" Text="{Binding Description}"
TextColor="#808080"
FontSize="Medium"></Label>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="Indicator" IndicatorColor="LightBlue"
SelectedIndicatorColor="DarkGray"></IndicatorView>
How Can I dynamically add the title and collection? I've gotten the carousel view to show but cannot get it to show when involving data and properties.
xmlns:control="clr-namespace:Program.Controls"
<control:CarouselControl Department="Human Resources" Collection="{Binding HumanResourcesCollection}"></control:CarouselControl>
<control:CarouselControl Department="Administration" Collection="{Binding AdministrationCollection}"></control:CarouselControl>
<control:CarouselControl Department="Operations" Collection="{Binding OperationsCollection}"></control:CarouselControl>
Am I in the right thinking or way off base? Been messing around with properties in a ViewModel but don't know enough to get it working. Thanks all.
public string Department {get; set;}
public ObservableCollectoin<DeparmentModel> Collection {get; set;}
回答1:
Since you had used Custom ContentView , you need use bindable property to binding value between the elements in ContentView and Parent ContentPage
in CarouselControl.xaml
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
//...
x:Name="view" // set the name of CarouselControl
>
<StackLayout Padding="10">
<Label Text="Human Resources" FontSize="Large"
TextColor="#000000"></Label>
<CarouselView ItemsSource="{Binding Source={x:Reference view}, Path=Collection}"
PeekAreaInsets="75"
IndicatorView="Indicator"
HeightRequest="275">
<CarouselView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" ItemSpacing="10"></LinearItemsLayout>
</CarouselView.ItemsLayout>
<CarouselView.EmptyView>
<StackLayout>
<Label Text="No results for this department"
FontSize="Large"
HorizontalOptions="Fill"
HorizontalTextAlignment="Center"></Label>
<Label Text="Contact your manager for more information"
FontSize="Medium"
HorizontalOptions="Fill"
HorizontalTextAlignment="Center"></Label>
</StackLayout>
</CarouselView.EmptyView>
<CarouselView.ItemTemplate>
<DataTemplate>
<StackLayout Padding="10">
<helper:LayoutGradient StartColor="{StaticResource Secondary}"
EndColor="{StaticResource Secondary}"
OptionCorner="True"
RadiusCorner="25"
DirectionColor="False">
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="OnDepartmentSelected></TapGestureRecognizer>
</Frame.GestureRecognizers>
<Frame.Content>
<Grid RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.Row="0" Aspect="AspectFit" Opacity=".35" VerticalOptions="End" HorizontalOptions="End">
<Image.Source>
<FontImageSource Size="148" Glyph="{Binding Comments}"
FontFamily="{DynamicResource FontIcons}"
Color="Blue"></FontImageSource>
</Image.Source>
</Image>
<StackLayout
Grid.Row="0" Grid.Column="0">
<Label Text="{Binding Title}" FontSize="Medium" FontAttributes="Bold"
></Label>
<Label Text="{Binding Version}" FontSize="Small"></Label>
</StackLayout>
</Grid>
</Frame.Content>
</helper:LayoutGradient>
<Label Padding="0, 10, 0, 10" Text="{Binding Source={x:Reference view}, Path=Description}"
TextColor="#808080"
FontSize="Medium"></Label>
</StackLayout>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="Indicator" IndicatorColor="LightBlue"
SelectedIndicatorColor="DarkGray"></IndicatorView>
in CarouselControl.xaml.cs
public static readonly BindableProperty CollectionProperty =
BindableProperty.Create(nameof(Collection), typeof(ObservableCollection<YourModel>), typeof(CarouselControl));
public ObservableCollection<YourModel> Collection
{
get => (ObservableCollection<YourModel>)GetValue(CollectionProperty );
set => SetValue(CollectionProperty , value);
}
Note : YourModel here is the mdoel that contains the properties of the CarouselView , like
public class YourModel
{
public string Title { get; set; }
public string Version { get; set; }
//...other proerty in CarouselView
}
in ContentPage
<control:CarouselControl Department="Human Resources" Collection="{Binding HumanResourcesCollection}"></control:CarouselControl>
You just need to binding the source of Collection, the property Title had been set when you init the HumanResourcesCollection so you don't need to binding it again .
Here is some similar case that you can have a refer
How to bind a CommandParameter in a ContentView to an element in the parent ContentPage in Xamarin Forms
When to use Xamarin bindings as opposed to passing objects to page constructors?
来源:https://stackoverflow.com/questions/64212190/include-dynamic-custom-xamarin-xaml-view-control