Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

VisualStates are not being applied to items in a CollectionView using DataTemplates in Release Mode #9756

Closed
EmberLynn opened this issue Aug 29, 2022 · 2 comments
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView area-xaml XAML, CSS, Triggers, Behaviors platform/android 🤖 s/needs-repro Attach a solution or code which reproduces the issue s/triaged Issue has been reviewed t/bug Something isn't working

Comments

@EmberLynn
Copy link

Description

This is a frustrating issue (which I am pretty sure is a bug) that only applies when I run our app in Release mode.

Currently, I have a dynamically rendered form. In this form, I have 2 sections. One section is a VerticalStackLayout of elements such as Editors, Entries, Pickers, and Date Pickers.

Here is an example of this section of the form:

<VerticalStackLayout Padding="5"
                     IsVisible="{Binding IsDetailsTabShowing}"
                     BackgroundColor="#f2f2f2">

  <VerticalStackLayout Style="{StaticResource FormVerticalLayout}">
      <Label Text="{Binding Request.RequestConfig.NameLabel}"
             FontAttributes="Bold"
             />
      <Frame Style="{StaticResource FormFieldFrame}">
          <Entry Placeholder="Enter your sentence here" Text="{Binding Request.Name}"
             Loaded="SubjectFieldFilled"
             TextChanged="SubjectFieldFilled"
             />
      </Frame>
  </VerticalStackLayout>

  <VerticalStackLayout Style="{StaticResource FormVerticalLayout}"
                       IsVisible="{Binding Request.RequestConfig.IsDescriptionVisible}">
      <Label Text="{Binding Request.RequestConfig.DescriptionLabel}"
             FontAttributes="Bold"
             />
      <Frame Style="{StaticResource FormFieldFrame}">
          <FlexLayout Wrap="Wrap">
              <Editor Placeholder="Enter your sentence here" 
                      Text="{Binding Request.Description}"
                      HeightRequest="100"
                      WidthRequest="330"
                      BackgroundColor="Transparent"
                      />
          </FlexLayout>
      </Frame>
  </VerticalStackLayout>
</VerticalStackLayout>

(The SubjectFieldFilled function sets the VisualState of the element)

The second section is a CollectionView that uses an ItemTemplateSelector to dynamically assign templates as each element in the CollectionView is loaded. Elements in the CollectionView are VerticalStackLayouts that contain Labels and an Editor or Picker or Entry and so on.

Here is what the CollectionView looks like:

<CollectionView x:DataType="model:CustomFormSection"
                ItemsSource="{Binding Rows}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <CollectionView x:DataType="model:CustomFormRow"
                            ItemsSource="{Binding Fields}"
                            ItemTemplate="{StaticResource CustomFieldsTemplateSelector}"
                            />
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

In addition to my form, I have created controls that apply a certain VisualState based on information in the page's overall binding. This control looks to see if a field in the form (Editor, Entry, Picker, and so on) is required to be filled out (contains data). From there, my control applies one of two VisualStates. The VisualState is either default (transparent background) or required (pink background).

Here is the code behind for setting the VisualState on a Picker (there is a different function depending on the VisualElement, but they are all setting the state to either Default or Required):

void OnPickerSelectedItem(object sender, EventArgs args)
{
    Picker picker = (Picker)sender;

    VisualStateManager.GoToState(picker, "DefaultState");

    currentElement = picker;

    if (picker.BindingContext is not null)
    {
        CustomFormField parameter = (CustomFormField)picker.BindingContext;

        if (picker.SelectedItem is null
            && parameter.IsRequired)
        {
            VisualStateManager.GoToState(picker, "RequiredState");
        }

        ToggleIsSubmitButtonEnabled();
    }
}

The VisualState is set for all elements when the element itself is loaded; I use the Loaded event on each item in the CollectionView. The Loaded event calls a function that sets that element's VisualState to Required or Default. After the page has loaded and each time the user inputs data into one of the form fields, the same function is called to see if that element's VisualState needs to be changed.

Here is an example of what one of the DataTemplates looks like:

<DataTemplate x:Key="PickerFieldTemplate">
    <VerticalStackLayout Style="{StaticResource FormVerticalLayout}"
                         x:DataType="model:CustomFormField">
        <Label Text="{Binding Name}"
               FontAttributes="Bold"
               />
        <Frame Style="{StaticResource FormFieldFrame}">
            <Picker x:Name="picker"
                    Title="Pick a value"
                    ItemsSource="{Binding Options}"
                    ItemDisplayBinding="{Binding Label}"
                    SelectedItem="{Binding SelectedOption}"
                    SelectedIndexChanged="OnPickerSelectedItem"
                    Loaded="OnPickerSelectedItem"
                    />
        </Frame>
    </VerticalStackLayout>
</DataTemplate>

(Both Loaded and SelectedIndexChanged events trigger the function that sets the VisualState of the Picker element)

And here is what our VisualStateGroupList looks like for the Picker (each element gets a VisualStateGroup list in the ResourceDictionary inside of the App.xaml page):

<Style TargetType="Picker">
    <Setter Property="VisualStateManager.VisualStateGroups">
        <VisualStateGroupList>
            <VisualStateGroup x:Name="CustomFieldPickerStates">
                <VisualState x:Name="Normal"/>
                <VisualState x:Name="RequiredState">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="Pink"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState x:Name="DefaultState">
                    <VisualState.Setters>
                        <Setter Property="BackgroundColor" Value="White"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateGroupList>
    </Setter>
</Style>

All of what I have described above works in Debug mode only. In Release Mode, the functions to change the state are being called, but visually the element never changes; it appears on screen with the default stylings set by MAUI. This is not a problem in the first section of my form where I am not using a CollectionView with DataTemplates.

I am wondering if this is simply a bug in trying to use VisualStates within a ColelctionView that uses a DataTemplateSelector to set items' appearance on screen.

For further reference, here are two screen captures of our app. One is how the app appears running in Debug mode and the other is how the app appears in Release mode.

Debug (stylings are applied):
Debug Mode

Release (stylings are not applied):
Release Mode

Steps to Reproduce

  1. Create a CollectionView that utilizes a custom DataTemplateSelector class.
  2. Create VisualStateGroups for elements that are to be rendered in the CollectionView
  3. Write a function in the code behind that sets the VisualState of each element when it renders on page

What I expect to happen: The VisualStates of each element are set accordingly.
What happens: VisualStates of elements appear to be set, but they are not styled accordingly.the

Version with bug

6.0.400

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 12

Did you find any workaround?

No

Relevant log output

No response

@EmberLynn EmberLynn added the t/bug Something isn't working label Aug 29, 2022
@jsuarezruiz jsuarezruiz added area-xaml XAML, CSS, Triggers, Behaviors area-controls-collectionview CollectionView, CarouselView, IndicatorView labels Aug 30, 2022
@PureWeen PureWeen added this to the Backlog milestone Sep 7, 2022
@ghost
Copy link

ghost commented Sep 7, 2022

We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.

@Zhanglirong-Winnie Zhanglirong-Winnie added the s/triaged Issue has been reviewed label Nov 30, 2023
@jsuarezruiz jsuarezruiz added the s/needs-repro Attach a solution or code which reproduces the issue label Mar 11, 2024
@dotnet-policy-service dotnet-policy-service bot added the s/no-recent-activity Issue has had no recent activity label Mar 18, 2024
Copy link
Contributor

This issue has been automatically marked as stale because it has been marked as requiring author feedback to reproduce the issue but has not had any activity for 4 days. It will be closed if no further activity occurs within 3 days of this comment. If it is closed, feel free to comment when you are able to provide the additional information and we will re-investigate.

@dotnet-policy-service dotnet-policy-service bot removed this from the Backlog milestone Mar 21, 2024
@github-actions github-actions bot locked and limited conversation to collaborators Apr 20, 2024
@dotnet-policy-service dotnet-policy-service bot removed the s/no-recent-activity Issue has had no recent activity label Apr 20, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView area-xaml XAML, CSS, Triggers, Behaviors platform/android 🤖 s/needs-repro Attach a solution or code which reproduces the issue s/triaged Issue has been reviewed t/bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants