问题描述
程序启动运行不报错,但开发时,只要查看.axaml文件时,Avalonia Diagnostics就报错,导致无法查看实时预览
原因分析
Object reference not set to an instance of an object
代码中使用了相对路径,设计模式预览时无法解析相对路径从而导致找不到文件,最后呈现的则是未将对象引用至实例化。比如你注入ORM时,对path
变量直接赋值appsettings.json
,从而使用了相对路径
"Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object."
An item with the same key has already been added.
使用了Nuget包Material.Styles.Controls
中的SnackbarHost
控件,这个控件有个bug,它的属性HostName
要求是唯一值,而你每修改一次,预览加载时会默认赋值时会报错,这个时候你会发现你随便改什么它都会报这个错,但是你把这个控件的属性HostName
重新赋值,报错会停止,但继续修改任意地方又会报错
[Error] 1168 UpdateXamlResult error
System.Xaml.XamlException: An item with the same key has already been added. Key: Root
解决方法
对于未将对象引用至实例化
这里提供一个案例,只要活用Design.IsDesignMode
很多报错都可以规避
public static AppConfig ImportConfig(string filePath)
{
try
{
if(Design.IsDesignMode)
{
filePath = AppDomain.CurrentDomain.BaseDirectory + "\\appconfig.json";
}
string json = File.ReadAllText(filePath);
return JsonSerializer.Deserialize<AppConfig>(json);
}
catch (Exception ex)
{
Console.WriteLine($"Error importing config: {ex.Message}");
return null;
}
}
这样做负责实时预览的后台线程会进入Design.IsDesignMode
里,从而使用了绝对路径,避免报错;而当启动运行时,则不会进入Design.IsDesignMode
中。
对于使用了SnackbarHost
在你完全设计好页面前,先把它注释掉,目前没找到很好的解决方法
<!--设计页面时请注释-->
<!--<controls:SnackbarHost HostName="Root" TemplateApplied="TemplatedControl_OnTemplateApplied">-->