Reputation: 135
I know this question has been asked many times but I haven't been able to make it work with the solutions provided in the other questions.
Here's the problem: I want to change the BackgroundColor of a frame when it is clicked and come back to it's color when another frame is clicked.
Page.xaml
<ScrollView Orientation="Horizontal" Grid.Row="1" HorizontalScrollBarVisibility="Never" BackgroundColor="Transparent">
<StackLayout Orientation="Horizontal"
Margin="15, 8, 0, 0">
<StackLayout Orientation="Horizontal" BindableLayout.ItemsSource="{Binding Categories}">
<BindableLayout.ItemTemplate>
<DataTemplate x:DataType="model:CategoryDTO">
<Frame BackgroundColor="{Binding Source={RelativeSource AncestorType={x:Type vm:PageViewModel}}, Path=FrameColor}"
CornerRadius="15"
VerticalOptions="Center"
HasShadow="False"
Padding="15, 8">
<Label Text="{Binding Name}"
FontSize="Micro"
HorizontalOptions="Center"
VerticalOptions="Center"
TextColor="White"
FontAttributes="Bold" />
<Frame.GestureRecognizers>
<TapGestureRecognizer
NumberOfTapsRequired="1"
Command="{Binding Source={RelativeSource AncestorType={x:Type vm:PageViewModel}}, Path=CategoryTapped}"
CommandParameter="{Binding .}">
</TapGestureRecognizer>
</Frame.GestureRecognizers>
</Frame>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
PageViewModel.cs
public class PageViewModel : BaseViewModel
{
public ObservableCollection<CategoryDTO> Categories { get; }
public string FrameColor { get; set; } = "#3d3d3d";
public PageViewModel()
{
Categories = new ObservableCollection<CategoryDTO>();
LoadCategoriesCommand = new Command(async () => await ExecuteLoadCategoriesCommand(), () => false);
CategoryTapped = new Command<CategoryDTO>(async (categoryId) => await OnCategoryTapped(categoryId));
}
public Command LoadCategoriesCommand { get; }
public Command<CategoryDTO> CategoryTapped { get; }
private async Task OnCategoryTapped(CategoryDTO categoryDTO)
{
IsBusy = true;
try
{
await ExecuteSomethingCommand(id);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}
finally
{
IsBusy = false;
}
}
}
Thank you so much for your help.
Upvotes: 0
Views: 1231
Reputation: 67
Your categoriesDTO should to realize INotifyPropertyChanged and in there include an IsSelected public property.
<Frame.Triggers>
<DataTrigger TargetType="Frame"
Binding="{Binding IsSelected}"
Value="True">
<Setter Property ="BackgroundColor" Value ="Yellow"/>
</DataTrigger>
<DataTrigger TargetType="Frame"
Binding="{Binding IsSelected}"
Value="False">
<Setter Property ="BackgroundColor" Value ="White"/>
</DataTrigger>
</Frame.Triggers>
Upvotes: 1
Reputation:
You can add focused event on Frame, like:
<Frame x:Name="frame1"
BackgroundColor="Blue"
Focused="onfocus">
</Frame>
<Frame x:Name="frame2"
BackgroundColor="Blue"
Focused="onfocus">
code behind:
public void onfocus(object obj, EventArgs e)
{
var myframe = obj as Frame;
myframe.BackgroundColor = Color.Red;
}
Upvotes: 0
Reputation: 101
I have created a sample app using prism MVVM that you can clone and run locally on your machine here
Upvotes: 0