Приложение на WinUI 3 нормально запускается в режиме Debug, но при сборке Release вылетает с ошибкой, текст исключения ниже:

За всё время разработки я редко встречал подобную ситуацию, кроме того исключения, выбрасываемые программами на WinUI 3, относятся к внутренним механизмам фреймворка — из стека вызовов почти невозможно извлечь полезную информацию для диагностики.
Методом исключения я выяснил, что ошибка возникает при инициализации ViewModel на странице Page, происходит исключение нулевого указателя. Поясню структуру проекта: это приложение WinUI 3 с одним главным окном, слева расположена панель меню. При клике по пункту меню в центральной правой части окна отображается отдельная страница Page. Код разметки главного окна для отображения страниц выглядит так:
<TabView Name="tabView" IsAddTabButtonVisible="False" Margin="10" VerticalAlignment="Stretch" TabCloseRequested="TabView_TabCloseRequested">
<TabViewItem x:Uid="tabConsonant" Name="tvHome">
</TabViewItem>
</TabView>Code language: plaintext (plaintext)
Данный блок отвечает за вывод контента справа, инициализирую содержимое tvHome в кодbehind главного окна:
private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
tvHome.Content = new ConsonantsPage();
}Code language: plaintext (plaintext)
Дальнейшая проверка показала, что сбой вызывает строка присвоения контекста данных на странице: this.DataContext = vm;

Я протестировал открыть другую страницу без привязки DataContext — она загружается без ошибок. Исходя из этого, точно установил, что проблема связана с механизмом привязок Binding. Пришлось искать альтернативный подход: отказаться от декларативных привязок в разметке XAML и формировать элементы программно в коде.
Итоговое рабочее решение:
Создавать элементы управления и связывать данные напрямую в бэкенд-коде
public TonePage()
{
InitializeComponent();
Loaded += Page_Loaded;
}
private void Page_Loaded(object sender, RoutedEventArgs e)
{
var toneData = ThaiAlphabetSource.Tones;
FillToneGrid(gvToneList, toneData);
}
private void FillToneGrid(GridView grid, List<ToneInfo> source)
{
foreach (var item in source)
{
Button btnRoot = new Button
{
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalContentAlignment = VerticalAlignment.Center,
Tag = item.Audio
};
btnRoot.Click += PlayClick;
StackPanel sp = new StackPanel
{
Width = 240,
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center
};
TextBlock tbTitle = new TextBlock
{
HorizontalAlignment = HorizontalAlignment.Center,
FontSize = 50,
Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0x01, 0xA0, 0xC7)),
Text = item.Letter_Title
};
TextBlock tbName = new TextBlock
{
HorizontalAlignment = HorizontalAlignment.Center,
FontSize = 30,
Text = item.Letter_Name
};
TextBlock tbScript = new TextBlock
{
HorizontalAlignment = HorizontalAlignment.Center,
FontSize = 30,
Text = item.Letter_Script
};
sp.Children.Add(tbTitle);
sp.Children.Add(tbName);
sp.Children.Add(tbScript);
btnRoot.Content = sp;
grid.Items.Add(btnRoot);
}
}Code language: plaintext (plaintext)
Я не стал глубоко копаться в корне неполадки, предполагаю, что конфликт возникает из-за привязок команд вида Command=»{Binding PlayCommand}». Если у вас появится аналогичная проблема — начните проверку именно с командных привязок. Мой вывод основан на другом участке кода с привязкой данных, но без команд — он работает стабильно, пример ниже:
<Button Content="{Binding}" Grid.Row="0" Grid.Column="1" BorderBrush="#ccc" Foreground="Black" FontSize="50" Height="100" Width="130" Click="Button_Click"/>Code language: plaintext (plaintext)
Этот фрагмент без привязки команд корректно работает в сборке Release.