Xử lý lỗi bất thường trong ứng dụng WinUI 3

Ứng dụng WinUI 3 hoạt động ổn ở chế độ Gỡ lỗi nhưng bị treo khi biên dịch bản Phát hành, chi tiết lỗi được hiển thị bên dưới.

Tôi hiếm khi gặp phải những lỗi kỳ lạ như thế này trong quá trình phát triển thông thường. WinUI 3 chủ yếu trả về các ngoại lệ thời gian chạy nội bộ, khiến việc tìm ra manh mối hữu ích từ ngăn xếp ngoại lệ trở nên khó khăn.

Sau nhiều vòng kiểm tra loại trừ, tôi xác định nguyên nhân gây treo là lỗi tham chiếu null xảy ra khi khởi tạo ViewModel bên trong một Trang. Cấu trúc dự án như sau: một cửa sổ chính có menu điều hướng bên cạnh. Khi nhấp vào các mục menu, trang đích sẽ được tải vào khu vực nội dung chính bên phải. Đoạn mã XAML được sử dụng tại cửa sổ chính như sau:

<TabView Name="tabView" IsAddTabButtonVisible="False" Margin="10" VerticalAlignment="Stretch" TabCloseRequested="TabView_TabCloseRequested">
    <TabViewItem x:Uid="tabConsonant" Name="tvHome">
    </TabViewItem>
</TabView>Code language: HTML, XML (xml)

TabView này dùng để hiển thị các trang nội dung ở bên phải. Tôi gán đối tượng Trang đích cho tvHome thông qua mã phía sau:

private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)
{
    tvHome.Content = new ConsonantsPage();
}Code language: JavaScript (javascript)

Việc gỡ lỗi thêm đã xác nhận lỗi treo xảy ra đúng tại dòng lệnh this.DataContext = vm; bên trong trang đích.

Sau đó, tôi thử một trang trống hoàn toàn không dùng DataContext và liên kết dữ liệu, trang này tải thành công mà không có lỗi. Vì vậy, nguyên nhân gốc rễ chắc chắn liên quan đến logic liên kết XAML. Thay vì tiếp tục sử dụng liên kết MVVM tiêu chuẩn, tôi đã chuyển sang tạo các thành phần giao diện bằng mã lập trình trực tiếp ở phần sau như một giải pháp tạm thời.

Giải pháp sửa lỗi hiệu quả cuối cùng:

Tạo điều khiển và liên kết giá trị hoàn toàn bằng mã C# phía sau:

 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
                {
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    FontSize = 50,
                    Foreground = new SolidColorBrush(Color.FromArgb(0xFF, 0x01, 0xA0, 0xC7)),
                    Text = item.Letter_Title
                };
                TextBlock tbName = new TextBlock
                {
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    FontSize = 30,
                    Text = item.Letter_Name
                };
                TextBlock tbScript = new TextBlock
                {
                    HorizontalContentAlignment = 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: PHP (php)

Tôi không tìm hiểu sâu hơn để xác định lỗi gốc chính xác, nhưng nghi vấn vấn đề xuất phát từ cú pháp liên kết lệnh như Command="{Binding PlayCommand}". Một trường hợp kiểm tra khác đã chứng minh giả định này: các trang chỉ dùng liên kết thuộc tính thông thường mà không có liên kết lệnh đều hoạt động ổn, ví dụ cụ thể bên dưới:

<Button Content="{Binding}" Grid.Row="0" Grid.Column="1" BorderBrush="#ccc" Foreground="Black" FontSize="50" Height="100" Width="130" Click="Button_Click"/>Code language: HTML, XML (xml)

Cách viết này hoạt động bình thường ở cấu hình Phát hành.

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *