dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.02k stars 1.73k forks source link

GraphicsView not shown / issue with IsVisible property #12903

Open espenrl opened 1 year ago

espenrl commented 1 year ago

Description

When IsVisible has been set to false and then back to true the GraphicsView is not shown. In fact the drawable is not ever called.

Steps to Reproduce

Create a GraphicsView with IsVisible = false initially.

Link to public reproduction project repository

N/A

Version with bug

7.0 (current)

Last version that worked well

Unknown/Other

Affected platforms

Android

Affected platform versions

Android 12

Did you find any workaround?

GraphicsViewHandler.Mapper.AppendToMapping(nameof(IGraphicsView.Visibility), MapVisibility);

private static void MapVisibility(IGraphicsViewHandler handler, IGraphicsView graphicsView)
{
    handler.PlatformView.Visibility = graphicsView.Visibility.ToPlatformVisibility();
}

Relevant log output

No response

ghost commented 1 year ago

Hi @espenrl. We have added the "s/needs-repro" label to this issue, which indicates that we require steps and sample code to reproduce the issue before we can take further action. Please try to create a minimal sample project/solution or code samples which reproduce the issue, ideally as a GitHub repo that we can clone. See more details about creating repros here: https://github.com/dotnet/maui/blob/main/.github/repro.md

This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.

jsuarezruiz commented 1 year ago

Could you attach a sample where reproduce the issue?. Cannot reproduce it. issue-12903

ghost commented 1 year ago

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.

espenrl commented 1 year ago

https://github.com/espenrl/issue-repro/blob/main/maui-android-graphicsview

Finally had the time to make a sample. I found out that the combination of IsVisible="False" and InputTransparent="True" is what triggers the issue. If IsVisible is initially true then it works as it should. Tested on SR3.

ghost commented 1 year ago

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.

mattleibow commented 1 year ago

I found the issue and I think this is all to do with the fact that when we do things that change the ContainerView, we are not correctly setting and unsetting the properties.

espenrl commented 1 year ago

Yes, the dynamic creation and destruction of ContainerView depending upon what properties are set makes it hard to track what properties to "transfer" between PlatformView and ContainerView. Might as weel always have the ContainerView for the lifetime of a view. Would that be an idea?

espenrl commented 1 year ago

IElementHandler.SetVirtualView() initializes a view with its property mappers. Some mappers run before creating a ContainerView, some run after. A few propery mappers that took action on the PlatformView now take action on the ContainerView. That leaves the view in an invalid state for the remainder of the lifetime. This is the cause of many of my problems regarding Opacity and IsVisible for all views, not just GraphicsView.

espenrl commented 1 year ago

These four trigger the ContainerView property mapper

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L246-L258

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L291-L296

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L326-L334

ContainerView property mapper

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L273-L281

ContainerView infrastructure

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L81-L96

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandler.cs#L98-L101

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/ViewExtensions.cs#L51-L73

NOTE: The following is the Android version

https://github.com/dotnet/maui/blob/04bfb275d9401a631d3e9a1e20665e68e99b79c4/src/Core/src/Handlers/View/ViewHandlerOfT.Android.cs#L20-L37

espenrl commented 1 year ago

What I can't figure out is why this problem manifest itself on Android, but not on iOS and Windows. And it seems logical that it should. It's probably something I don't know about property mapper initialization across the platforms.

arahmancsd commented 1 year ago

I am experiencing the same thing inside a CollectionView ItemTemplate.

Place a GraphicsView item inside a data template in CollectionView with IsVisible = {Binding ViewModelVisibleProperty}. Then update the ViewModel accordingly with ViewModelVisibleProperty = True for the specific CollectionView item. The GraphicsView doesn't show up in the view.

beeradmoore commented 1 month ago

@jsuarezruiz I think this issue is the same as something I've just come across. If not please let me know and I'll file as a new issue.

Repro: https://github.com/beeradmoore/maui-issue-IsVisibleBindingTest

This repro project is using CommunityToolkit.MVVM. I have a MainPageModel which has a property calledIsSelected. IsSelected is false by default.

There is a red BoxView in the middle of the page which has its IsVisible bound to the IsSelected on the MainPageModel. So its IsVisible is false by default.

IsSelected is toggled by a button in the top left that says "Toggle IsSelected: {current state true/false}".

When I run this in the iOS simulator I have no red box (as expected) but when I hit the button I still do not have a red box. On macOS I have the same behaviour.

HOWEVER, on macOS if I take focus away from the window the red box will appear. On iOS rotating the simulator does not make it appear.

In the project (not the repro) I have that I found this problem with if I resize the window on macOS the box will appear (EDIT: This happens if I take focus away, not resize, my mistake). In that project the box is a SkiaSharp SKCanvasView. I also observe there that its X/Y/Width/Height gets measured for the first time when the window is resized. This me think its size/layout is not calcualted when it is added to the window.

I added a BoxView_OnPropertyChanged event onto the BoxView but I don't think it's doing anything odd.

BoxView_OnPropertyChanged - HorizontalOptions
BoxView_OnPropertyChanged - VerticalOptions
BoxView_OnPropertyChanged - WidthRequest
BoxView_OnPropertyChanged - HeightRequest
BoxView_OnPropertyChanged - Parent
BoxView_OnPropertyChanged - IsVisible
BoxView_OnPropertyChanged - Window
-> clicked button here
BoxView_OnPropertyChanged - IsVisible
BoxView_OnPropertyChanged - X - 749
BoxView_OnPropertyChanged - Y - 381
BoxView_OnPropertyChanged - Width - 100
BoxView_OnPropertyChanged - Height - 100

I initially thought it was not measuring its x/y/w/h and thats why it wasn't visible. But this shows it does measure it, just not when the page is laid out.

I tested all lof this on an Android Emulator and it appeared to perform correctly.

EDIT: Tested this on Windows and it worked correctly. Issue appears to just be iOS and macOS.

EDIT 2: Playing around with Maui.Controls.Sample.Sandbox and stepping through things. I set up something similar to above, I have it IsSelected=false. I have a bunch of console output and break points in various Draw methods in other classes like DirectRenderer.

I hit the button once and then click off the window to step through what happens.

It looks like Draw is not called in PlatformGraphicsView for my BoxView, even when its visibility is toggled. It only gets called when the window loses focus. Even when I make the window lose focus while the toggle is set to false it will go through the draw code. I guess at that level something is preventing it from drawing.

In these tests I was able to tell which was my box as the dirtyRect passed around was 0,0,100,100 not 0,0,967,655 which I assume is my windows background or something.