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

DataContext value in DevTools displayed as null if type of value inherited from System.ComponentModel.Component #15877

Open
BreakByBrick opened this issue May 31, 2024 · 3 comments
Labels

Comments

@BreakByBrick
Copy link

Describe the bug

Hello!

When ViewModel is inherited from System.ComponentModel.Component, it displays in DataContext value of DevTools.

image

But in debug DataContext has value.

image

image

To Reproduce

https://github.com/BreakByBrick/Avalonia.Issue/tree/main/DevTools.DataContextWithComponentDisplaysNull

image

Expected behavior

The DataContext value in DevTools must not be null.

Avalonia version

11.0.10

OS

Windows

Additional context

No response

@stevemonaco
Copy link
Contributor

stevemonaco commented May 31, 2024

The type to text ultimately goes through:

public static string? ToString(object o)
{
var converter = TypeDescriptor.GetConverter(o);
//CollectionConverter does not deliver any important information. It just displays "(Collection)".
if (!converter.CanConvertTo(typeof(string)) ||
converter.GetType() == typeof(CollectionConverter))
return o.ToString();
return converter.ConvertToInvariantString(o);
}

Component has a .NET type, ComponentConverter, that is being used to ConvertToInvariantString(...) which goes through ConvertTo in this case. Component and string aren't really convertible, so it returns null.

So the fix is probably to add another special case to the if so the type name is returned:

if (!converter.CanConvertTo(typeof(string)) ||
    converter.GetType() == typeof(CollectionConverter) ||
    converter.GetType() == typeof(ComponentConverter))
    return o.ToString();

I can PR if this seems reasonable to a maintainer. I'm not familiar with Component at all. ie. Should we force the type string to be returned or can/should the app dev write a custom+default implementation?

@jp2masa
Copy link
Contributor

jp2masa commented May 31, 2024

Maybe it should just fallback to o.ToString()?

return converter.ConvertToInvariantString(o) ?? o.ToString();

or

if (!converter.CanConvertTo(typeof(string)) ||
    converter.GetType() == typeof(CollectionConverter) ||
    converter.ConvertToInvariantString(o) is not { } converted)
    return o.ToString();

return converted;

@stevemonaco
Copy link
Contributor

stevemonaco commented May 31, 2024

I misdiagnosed because this is a bit nonsensical. converter.ConvertToInvariantString(o) for ComponentConverter actually returns an empty string after double-checking, so null fallback won't work. DevTools then somewhere along the line interprets this as (null) and I don't yet understand how/where.

Even simpler, you can repro with <TextBlock Text="" />, on 11.0.10 and nightly. The DevTools display will be (null).

Explicit ComponentConverter check might still be necessary?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants