Page 1 of 1

Exception in LocExtension when being used by blend designer

Posted: 26 Feb 2024, 23:48
by samc
I've been tracking down an issue in the blend designer where an exception is being thrown when rendering one of my views.

I have a user control that looks like this:
    public partial class VoiceViewSession : UserControl
    {
        public VoiceViewSession()
        {
            InitializeComponent();
        }

        private static readonly DependencyProperty _labelBackgroundProperty =
            DependencyProperty.Register("SessionLabelBackground", typeof(Brush), typeof(VoiceViewSession), new PropertyMetadata(null));

        public Brush SessionLabelBackground
        {
            get { return (Brush)GetValue(_labelBackgroundProperty); }
            set { SetValue(_labelBackgroundProperty, value); }
        }

        private static readonly DependencyProperty _labelTextProperty =
            DependencyProperty.Register("SessionLabelText", typeof(string), typeof(VoiceViewSession), new PropertyMetadata(null));

        public string SessionLabelText
        {
            get { return (string)GetValue(_labelTextProperty); }
            set { SetValue(_labelTextProperty, value); }
        }

#if NOESIS
        private void InitializeComponent()
        {
            NoesisUnity.LoadComponent(this);
        }
#endif
    }
I'm using this user control in another xaml:

I have a xaml using a custom control:
<local:VoiceViewSession DataContext="{Binding Voice.SessionParty}" SessionLabelBackground="Purple" SessionLabelText="{noesis:Loc Text.InGame.Voice.Channel.Party}"/>
and the problem I'm seeing is that an exception is being thrown from the loc extension in LocExtension.cs, line 46, in the ProvideValue function:
	public override object ProvideValue(IServiceProvider serviceProvider)
	{
		if (!(serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget provideValueTarget))
		{
			return null;
		}
		DependencyObject dependencyObject = (DependencyObject)provideValueTarget.TargetObject;
		DependencyProperty targetProperty = (DependencyProperty)provideValueTarget.TargetProperty; //  <==== Exception being thrown here
		LocMonitor locMonitor = (LocMonitor)dependencyObject.GetValue(MonitorProperty);
		if (locMonitor == null)
		{
			locMonitor = new LocMonitor(dependencyObject);
			dependencyObject.SetValue(MonitorProperty, locMonitor);
		}
		return locMonitor.AddDependencyProperty(targetProperty, _resourceKey);
	}
This is the exception being thrown:
System.InvalidCastException
  HResult=0x80004002
  Message=Unable to cast object of type 'System.Reflection.RuntimePropertyInfo' to type 'System.Windows.DependencyProperty'.
  Source=Noesis.GUI.Extensions
  StackTrace:
   at NoesisGUIExtensions.LocExtension.ProvideValue(IServiceProvider serviceProvider) in NoesisGUIExtensions\LocExtension.cs:line 46
I'm not sure what I might be doing wrong exactly. I'll keep fiddling around with the code here, but thought I'd ask here to see if I'm doing something dumb.

thanks,
sam

Re: Exception in LocExtension when being used by blend designer

Posted: 27 Feb 2024, 02:54
by samc
I'm also sometimes seeing an error on line 45:
		DependencyObject dependencyObject = (DependencyObject)provideValueTarget.TargetObject;
the exception being:
System.InvalidCastException: 'Unable to cast object of type 'System.Windows.SharedDp' to type 'System.Windows.DependencyObject'.'

Re: Exception in LocExtension when being used by blend designer

Posted: 27 Feb 2024, 13:33
by maherne
Hi samc,

I have reproduced your issue, it is happening when ProvideValue is called for LocExtension when a template it is in is being loaded. During this call there are no valid targets, and a non-null value should be returned.

Could you create a ticket for this on our bugtacker, I'll provide LocExtension.cs with a fix for this for you to test.

Thanks!