maui icon indicating copy to clipboard operation
maui copied to clipboard

Exception "this element is not in a namescope" when using Setter with TargetName for VisualState = Normal

Open tgudelj opened this issue 1 year ago • 6 comments

Description

When using Setter with TargetName inside VisualStateManager a runtime exception is thrown:

System.InvalidOperationException' occurred in Microsoft.Maui.Controls.Xaml.dll but was not handled in user code
this element is not in a namescope

After a bit of trial and error it seems that error manifests only when using setter inside VisualStateGroup with name "Normal".

What am I doing wrong?

Steps to Reproduce

  1. Create new MAUI app
  2. add a simple layout to the MainPage
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="TestMauiCustomCtl.MainPage">

    <HorizontalStackLayout x:Name="ItemHorizontalStack" HorizontalOptions="Center" VerticalOptions="Center" Padding="20">
          <Label  x:Name="ItemLabel"
                      Text="This is the label inside"
                      FontSize="18" />
          <VisualStateManager.VisualStateGroups>
              <VisualStateGroupList>
                  <VisualStateGroup x:Name="CommonStates">
                      <VisualState x:Name="Normal">
                          <VisualState.Setters>
                              <Setter Property="BackgroundColor" Value="Red" />
                              <!--<Setter TargetName="ItemLabel" Property="Label.BackgroundColor" Value="Green" />-->
                          </VisualState.Setters>
                      </VisualState>
  
                      <VisualState x:Name="PointerOver">
                          <VisualState.Setters>
                              <Setter Property="BackgroundColor" Value="Yellow" />
                              <Setter TargetName="ItemLabel" Property="Label.BackgroundColor" Value="Black" />
                          </VisualState.Setters>
                      </VisualState>
                  </VisualStateGroup>
              </VisualStateGroupList>
          </VisualStateManager.VisualStateGroups>
    </HorizontalStackLayout>

</ContentPage>
  1. Run the app, no exceptions noted
  2. Uncomment the setter
  3. Run the app and Exception is thrown

Link to public reproduction project repository

https://github.com/tgudelj/mauibugrepro

Version with bug

7.0.86

Last version that worked well

Unknown/Other

Affected platforms

Windows

Affected platform versions

net7.0-windows10.0.19041.0

Did you find any workaround?

Obvious one is do not use setters with TargetName inside <VisualState x:Name="Normal">

Relevant log output

Exception thrown: 'System.InvalidOperationException' in Microsoft.Maui.Controls.Xaml.dll
An exception of type 'System.InvalidOperationException' occurred in Microsoft.Maui.Controls.Xaml.dll but was not handled in user code
this element is not in a namescope

tgudelj avatar Jul 18 '23 12:07 tgudelj

Verified this on Visual Studio Enterprise 17.8.0 Preview 1.0. Repro on Windows 11(8.0.100-preview.6.23330.14), not repro on Android 13.0-API33 and iOS 16.4 with below Project:

TestMauiCustomCtl.zip

XamlTest avatar Aug 09 '23 06:08 XamlTest

Update: Visual Studio Community 17.7.3 bug manifests on Windows and Android when build is set to Release

tgudelj avatar Aug 30 '23 07:08 tgudelj

@XamlTest Hello

   <DataTemplate x:Key="itemsTemplate" x:DataType="vo:QualityInspectionVo">
  
       <Grid>
           <Border
               x:Name="border"
               Margin="5"
               Padding="5"
               Stroke="Black">
               <Border.StrokeShape>
                   <RoundRectangle CornerRadius="5" />
               </Border.StrokeShape>
               <Grid>
                   <!--<Label FontAttributes="Bold" Text="{Binding Scantime, StringFormat='Time:{0:HH:mm}'}" />-->
               </Grid>
           </Border>
       </Grid>
   </DataTemplate>


      <Style TargetType="Grid">
          <Setter Property="VisualStateManager.VisualStateGroups">
              <VisualStateGroupList>
                  <VisualStateGroup x:Name="CommonStates">
                      <VisualState x:Name="Normal">
                          <VisualState.Setters>
                              <Setter TargetName="border" Property="Border.BackgroundColor" Value="White" />
                          </VisualState.Setters>
                      </VisualState>
                      <VisualState x:Name="Selected">
                          <VisualState.Setters>
                              <Setter TargetName="border" Property="Border.BackgroundColor" Value="LightSkyBlue" />
                          </VisualState.Setters>
                      </VisualState>
                  </VisualStateGroup>
              </VisualStateGroupList>
          </Setter>
      </Style>

       <CollectionView
           EmptyView="No items to display"
           ItemTemplate="{StaticResource itemsTemplate}"
           SelectionMode="Single" />

I tested my program on Android and it crashed (in release mode), but it worked fine in debug mode. If I delete <VisualState x:Name="Normal">, it won't crash. The crash log is 4619 4619 E AndroidRuntime: android.runtime.JavaProxyThrowable: Microsoft.Maui.Controls.Xaml.XamlParseException: Cannot resolve 'border' as Setter Target for 'Microsoft.Maui.Controls.Grid'.

nnn149 avatar Sep 08 '23 07:09 nnn149

@nnn149 Verified on Android Release mode, application crashes, but no exception or error can be caught.

XamlTest avatar Sep 12 '23 09:09 XamlTest

Issue seems to still be present in .net 8

tgudelj avatar Nov 27 '23 09:11 tgudelj

Also faced with this issue in .NET 8. It throws Exception for Windows application, but works fine on Android for me in Debug mode.

vitalbit avatar Jan 11 '24 10:01 vitalbit

I hit this one as well. A workaround would be great.

MartyIX avatar Jan 22 '24 14:01 MartyIX

Same thing happens to us in Android and iOS.

Installed Workload Id      Manifest Version       Installation Source
------------------------------------------------------------------------------------
android                    34.0.52/8.0.100        VS 17.9.34723.18, VS 17.9.34321.82
maui-windows               8.0.7/8.0.100          VS 17.9.34723.18, VS 17.9.34321.82
maccatalyst                17.2.8004/8.0.100      VS 17.9.34723.18, VS 17.9.34321.82
ios                        17.2.8004/8.0.100      VS 17.9.34723.18, VS 17.9.34321.82

mavispuford avatar Apr 18 '24 22:04 mavispuford

Facing this on Windows build in debug mode. I'm using VS2022 (17.9.6) with .NET 8. Is there a workaround for it?

Edit

Further digging reveals that using TargetName="MyControlName" in DataTrigger's Setter causes this issue. The code looks like this:

<Grid>
  <Image
      x:Name="UserImage"
      Source="{Binding LoggedInUser.image_url, TargetNullValue={x:Null}, FallbackValue={x:Null}}"
      Aspect="AspectFill"
      VerticalOptions="Fill"
      HorizontalOptions="Fill" />

  <Border Stroke="{StaticResource ThemeBorderBrush}" StrokeThickness="7"  StrokeShape="RoundRectangle 64,64,64,64"
          WidthRequest="128" HeightRequest="128">
  </Border>

  <Grid.Style>
    <Style TargetType="Grid">
      <Setter TargetName="UserImage" Property="IsVisible" Value="True" />
      <Style.Triggers>
        <DataTrigger TargetType="Border" Binding="{Binding LoggedInUser.image_url}" Value="{x:Null}">
          <Setter TargetName="UserImage" Property="IsVisible" Value="False" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Grid.Style>
</Grid>

Shujee avatar Apr 23 '24 16:04 Shujee

Here is the stack trace I get. (Android, Release Mode only)

System.InvalidOperationException: this element is not in a namescope
   at Microsoft.Maui.Controls.Element.FindByName(String name)
   at Microsoft.Maui.Controls.Setter.UnApply(BindableObject target, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.TriggerBase.OnConditionChanged(BindableObject bindable, Boolean oldValue, Boolean newValue)
   at Microsoft.Maui.Controls.PropertyCondition.OnStatePropertyChanged(BindableObject bindable, Object oldValue, Object newValue)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.SetValue(BindableProperty property, Object value)
   at Microsoft.Maui.Controls.PropertyCondition.OnAttachedObjectPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at Microsoft.Maui.Controls.BindableObject.OnPropertyChanged(String propertyName)
   at Microsoft.Maui.Controls.Element.OnPropertyChanged(String propertyName)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Apply(Object context, BindableObject bindObj, BindableProperty targetProperty, Boolean fromBindingContextChanged, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.BindableObject.ApplyBindings(Boolean skipBindingContext, Boolean fromBindingContextChanged)
   at Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
   at Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
   at Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__93_0(BindableObject child, Object bc)
   at Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
   at Microsoft.Maui.Controls.Element.OnBindingContextChanged()
   at Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
   at Microsoft.Maui.Controls.View.OnBindingContextChanged()
   at Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
   at Microsoft.Maui.Controls.Element.SetChildInheritedBindingContext(Element child, Object context)
   at Microsoft.Maui.Controls.Element.<OnBindingContextChanged>b__93_0(BindableObject child, Object bc)
   at Microsoft.Maui.Controls.BindableObjectExtensions.PropagateBindingContext[Element](BindableObject self, IEnumerable`1 children, Action`2 setChildBindingContext)
   at Microsoft.Maui.Controls.Element.OnBindingContextChanged()
   at Microsoft.Maui.Controls.VisualElement.OnBindingContextChanged()
   at Microsoft.Maui.Controls.View.OnBindingContextChanged()
   at Microsoft.Maui.Controls.BindableObject.SetInheritedBindingContext(BindableObject bindable, Object value)
   at Microsoft.Maui.Controls.Element.SetParent(Element value)
   at Microsoft.Maui.Controls.Element.OnChildRemoved(Element child, Int32 oldLogicalIndex)
   at Microsoft.Maui.Controls.VisualElement.OnChildRemoved(Element child, Int32 oldLogicalIndex)
   at Microsoft.Maui.Controls.Element.RemoveLogicalChild(Element element, Int32 index)
   at Microsoft.Maui.Controls.Element.RemoveLogicalChild(Element element)
   at Microsoft.Maui.Controls.Layout.Clear()
   at CommunityToolkit.Maui.Layouts.StateContainerController.SwitchToState(String state)
   at CommunityToolkit.Maui.Layouts.StateContainer.ChangeState(BindableObject bindable, String state)
   at CommunityToolkit.Maui.Layouts.StateContainer.OnCurrentStateChanging(BindableObject bindable, Object oldValue, Object newValue)
   at Microsoft.Maui.Controls.BindableObject.SetValueActual(BindableProperty property, BindablePropertyContext context, Object value, Boolean currentlyApplying, SetValueFlags attributes, SetterSpecificity specificity, Boolean silent)
   at Microsoft.Maui.Controls.BindableObject.SetValueCore(BindableProperty property, Object value, SetValueFlags attributes, SetValuePrivateFlags privateAttributes, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].ApplyCore(Object sourceObject, BindableObject target, BindableProperty property, Boolean fromTarget, SetterSpecificity specificity)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Apply(Boolean fromTarget)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2.PropertyChangedProxy[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].<OnPropertyChanged>b__16_0()
   at Microsoft.Maui.Controls.DispatcherExtensions.DispatchIfRequired(IDispatcher dispatcher, Action action)
   at Microsoft.Maui.Controls.Internals.TypedBinding`2.PropertyChangedProxy[[SIAppSrc.Pages.Quote.QuoteSelectCreatePage, SIAppSrc, Version=1.8928.32.0, Culture=neutral, PublicKeyToken=null],[System.String, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at Microsoft.Maui.Controls.BindingExpression.WeakPropertyChangedProxy.OnPropertyChanged(Object sender, PropertyChangedEventArgs e)
   at Microsoft.Maui.Controls.BindableObject.OnPropertyChanged(String propertyName)
   at Microsoft.Maui.Controls.Element.OnPropertyChanged(String propertyName)
   at SIAppSrc.Pages.Quote.QuoteSelectCreatePage.set_State(String value)
   at SIAppSrc.Pages.Quote.QuoteSelectCreatePage.CustomerNext_Clicked(Object sender, EventArgs e)

gerdus avatar Jun 25 '24 07:06 gerdus