VisualStateManager изменить фоновый фрейм / pancakeview не работает

#xamarin.forms

#xamarin.forms

Вопрос:

Проблема

  • Визуальный диспетчер состояний не запускается
  • Как мне изменить фон выбранного фрейма?

Любые предложения о том, что я делаю неправильно?

введите описание изображения здесь

Мне нужно создать горизонтальный список с набором фреймов, которые при выборе меняют цвет фона.

Очевидной реализацией будет CollectionView, у которого есть SelectedItem, который будет просто работать, так в чем проблема с этим?

Ну, если у вас есть pancakeView / frame с закругленными углами в iOS, вы можете увидеть серый фон и сообщение об ошибке в формах xamarin.

Итак, я решил реализовать bindableLayout, это работает нормально, однако я перепробовал все виды, но я не могу изменить цвет фона блина / фрейма и метки при выборе, ниже то, что я сделал

Главная страница

         <ContentPage.Resources>
            <ResourceDictionary>
                <Style TargetType="Grid">
                    <Setter Property="VisualStateManager.VisualStateGroups">
                        <VisualStateGroupList>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualState x:Name="Normal" />
                                <VisualState x:Name="Focused">
                                    <VisualState.Setters>
                                        <Setter Property="BackgroundColor" Value="LightSkyBlue" />
                                        <Setter TargetName="LabelA" Property="Label.TextColor" Value="Red"/>
                                        <Setter TargetName="Labelb" Property="Label.TextColor" Value="Red"/>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateGroupList>
                    </Setter>
                </Style>
            </ResourceDictionary>
        </ContentPage.Resources>
            <FlexLayout x:Name="Flex" 
                        Direction="Row" 
                        BindableLayout.ItemsSource="{Binding Cities}" 
                        Position="Relative" 
                        AlignItems="Start" 
                        FlowDirection="LeftToRight" 
                        JustifyContent="SpaceEvenly">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <Grid x:Name="myGrid" Padding="8,0" FlexLayout.AlignSelf="Start" >
                            <pancakeView:PancakeView x:Name="myPancake" 
                                                     Padding="20" 
                                                     Margin="5" 
                                                     CornerRadius="5" 
                                                     WidthRequest="60" 
                                                     HeightRequest="60" 
                                                     BackgroundColor="White" >
                                <pancakeView:PancakeView.Border>
                                    <pancakeView:Border Thickness="1" Color="Blue"  />
                                </pancakeView:PancakeView.Border>

                                <StackLayout >
                                    <Label x:Name="LabelA" Margin="0,0,0,0"
                                                           Text="{Binding Name }"
                                                           TextColor="Gray"
                                                           HorizontalOptions="Center" VerticalOptions="Center">
                                    </Label>
                                    <Label x:Name="Labelb" VerticalOptions="EndAndExpand"
                                                           HorizontalTextAlignment="Center" 
                                                           TextColor="Gray" 
                                                           FontSize="12"
                                                           Text="SomeText Here" />
                                </StackLayout>
                                <pancakeView:PancakeView.GestureRecognizers>
                                    <TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped">

                                    </TapGestureRecognizer>
                                </pancakeView:PancakeView.GestureRecognizers>
                            </pancakeView:PancakeView>
                        </Grid>
                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </FlexLayout>

    </ContentPage>
  

КОД ГЛАВНОЙ СТРАНИЦЫ ПОЗАДИ

     using System;
    using Xamarin.Forms;

    namespace BlankApp2.Views
    {
        public partial class MainPage
        {
            string currentColorState = "Normal";
            public MainPage()
            {
                InitializeComponent();
            }

            private void TapGestureRecognizer_OnTapped(object sender, EventArgs e)
            {
                currentColorState = currentColorState == "Normal" ? "Focused" : "Normal";

                //below has errors since "myPancake, LabelA Labelb are not recognized WHY????

                //  VisualStateManager.GoToState(myPancake,_currentColorState);
                //  VisualStateManager.GoToState(LabelA, _currentColorState);
                // VisualStateManager.GoToState(Labelb, _currentColorState);
            }
        }
    }
  

VIEWMODEL

     using Prism.Navigation;
    using System.Collections.ObjectModel;

    namespace BlankApp2.ViewModels
    {
        public class MainPageViewModel : ViewModelBase
        {
            public MainPageViewModel(INavigationService navigationService)
                : base(navigationService)
            {
                Title = "Main Page";
                Cities = GetCities();

            }
            private ObservableCollection<City> cities;
            public ObservableCollection<City> Cities
            {
                get => cities;
                set => SetProperty(ref cities, value);
            }
            private ObservableCollection<City> GetCities()
            {
                var list = new ObservableCollection<City>
                {
                    new City {Name = "London"},
                    new City {Name = "Rome"},
                    new City {Name = "New York"}
                };

                return list;
            }
        }
        public class City
        {
            public string Name { get; set; }
        }
    }
  

Ответ №1:

Попробуйте добавить VisualStateManager.VisualStateGroups свой фрейм / pancakeviw (здесь я тестирую с помощью frame).

создайте пользовательский фрейм:

 class MyFrame :Frame
{
    public bool IsFoucs { get; set; }
}
  

страница.xaml:

 <ContentPage.Resources>
    <ResourceDictionary>
        <Style TargetType="local:MyFrame">
            <Setter Property="VisualStateManager.VisualStateGroups">
                <VisualStateGroupList>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal" >
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="White" />
                                <Setter TargetName="LabelA" Property="Label.TextColor" Value="Gray"/>
                                <Setter TargetName="Labelb" Property="Label.TextColor" Value="Gray"/>
                            </VisualState.Setters>
                        </VisualState>
                        <VisualState x:Name="Focused">
                            <VisualState.Setters>
                                <Setter Property="BackgroundColor" Value="LightSkyBlue" />
                                <Setter TargetName="LabelA" Property="Label.TextColor" Value="Red"/>
                                <Setter TargetName="Labelb" Property="Label.TextColor" Value="Red"/>
                            </VisualState.Setters>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateGroupList>
            </Setter>
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>
<FlexLayout x:Name="Flex" 
                    Direction="Row" 
                    BindableLayout.ItemsSource="{Binding Cities}" 
                    Position="Relative" 
                    AlignItems="Start" 
                    FlowDirection="LeftToRight" 
                    JustifyContent="SpaceEvenly">
    <BindableLayout.ItemTemplate>
        <DataTemplate>
            <Grid x:Name="myGrid" Padding="8,0" FlexLayout.AlignSelf="Start" >
                <local:MyFrame x:Name="myPancake" 
                                                 Padding="20" 
                                                 Margin="5" 
                                                 CornerRadius="5" 
                                                 WidthRequest="60" 
                                                 HeightRequest="60" 
                                                 BorderColor="Blue"
                                                 BackgroundColor="White" >
           

                    <StackLayout >
                        <Label x:Name="LabelA" Margin="0,0,0,0"
                                                       Text="{Binding .}"
                                                       TextColor="Gray"
                                                       HorizontalOptions="Center" VerticalOptions="Center">
                        </Label>
                        <Label x:Name="Labelb" VerticalOptions="EndAndExpand"
                                                       HorizontalTextAlignment="Center" 
                                                       TextColor="Gray" 
                                                       FontSize="12"
                                                       Text="SomeText Here" />
                    </StackLayout>
                    <local:MyFrame.GestureRecognizers>
                        <TapGestureRecognizer Tapped="TapGestureRecognizer_OnTapped">

                        </TapGestureRecognizer>
                    </local:MyFrame.GestureRecognizers>
                </local:MyFrame>
            </Grid>
        </DataTemplate>
    </BindableLayout.ItemTemplate>
</FlexLayout>
  

затем в page.cs:

 private void TapGestureRecognizer_OnTapped(object sender, EventArgs e)
    {
        foreach (var item in Flex.Children)
        {
            MyFrame frame = (MyFrame)item.FindByName("myPancake");
            frame.IsFoucs = false;
            VisualStateManager.GoToState(frame, "Normal");
        }
        MyFrame myFrame = sender as MyFrame;
        myFrame.IsFoucs = !myFrame.IsFoucs;
        VisualStateManager.GoToState(myFrame, myFrame.IsFoucs ? "Focused" : "Normal");
    }
  

эффект выглядит следующим образом:

введите описание изображения здесь

Комментарии:

1. Привет, большое спасибо за ваше время, скопировал код и частично работает. По некоторым причинам выбирается все, что вы нажимаете, и не отменяет выбор предыдущего выбранного фрейма. Что происходит, так это то, что вы нажимаете на первый, это нормально, 2-е нажатие требует двойного нажатия, прежде чем оно будет выбрано, но предыдущий выбор не отменяется. Очевидно, вы не понимаете такого поведения, не так ли?

2. Я даже пробовал с DataTriggers и не смог заставить его работать.

3. @developer9969 Это моя ошибка, так как я использую одно и то же currentColorState для каждого фрейма. Вы можете проверить обновление выше, я создаю пользовательский фрейм и добавляю к нему свойство bool.

4. Привет, теперь двойное нажатие не требуется, если оставить все остальные выбранные фреймы. есть ли способ зациклить и отменить выбор всего фрейма перед его установкой. Работает ли это в вашем примере? еще раз спасибо за ваше время

5. @developer9969 Вы имеете в виду единый выбор?