Kỹ thuật truy xuất ResourceDictionary và DataTemplate trong Avalonia sử dụng C#

Khi phát triển ứng dụng Avalonia, sẽ có những tình huống bạn cần khởi tạo các phần tử giao diện một cách động, đòi hỏi việc chuyển đối tượng IDataTemplate vào các hàm. Thông thường, DataTemplate được định nghĩa trong tệp XAML, khiến việc truy cập trực tiếp từ mã C# trở nên khó khăn. Khác với một số framework khác, việc khởi tạo ResourceDictionary trong Avalonia đòi hỏi quy trình cụ thể, đặc biệt khi bạn đang tuân thủ nghiêm ngặt mẫu MVVM, nơi ViewModel không được phép tương tác trực tiếp với View.

Bài viết này sẽ hướng dẫn cách lấy ra các đối tượng DataTemplateResourceDictionary đã định nghĩa trong XAML để sử dụng trong code-behind hoặc ViewModel.

1. Thiết lập ResourceDictionary

Đầu tiên, hãy tạo một thư mục tên là Assets trong dự án của bạn (ví dụ: dự án tên là DemoApp). Bên trong thư mục này, thêm một item mới là Avalonia Resource Dictionary và đặt tên là GlobalResources.axaml.

Trong tệp GlobalResources.axaml, chúng ta sẽ định nghĩa một DataTemplate đơn giản cho TextBlock:

<ResourceDictionary xmlns="https://github.com/avaloniaui"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="MessageTemplate">
        <Border Padding="15" CornerRadius="5" Background="LightGray">
            <TextBlock Text="Nội dung mẫu" FontWeight="Bold" />
        </Border>
    </DataTemplate>
</ResourceDictionary>

2. Đăng ký tài nguyên trong App.axaml

Để tài nguyên này có thể được truy xuất toàn cục, bạn cần kết hợp (merge) nó vào App.axaml. Có hai cách phổ biến để thực hiện việc này.

Sử dụng đường dẫn tương đối (Avalonia XAML)

Cách này sử dụng đường dẫn URi cơ bản. Hãy chắc chắn rằng bạn thêm dấu gạch chéo / ở đầu đường dẫn:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceInclude Source="/Assets/GlobalResources.axaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

Sử dụng AvaloniaResource (avares://)

Cách tiếp cận này thường an toàn hơn và tránh lỗi đường dẫn. Bạn cần đổi thuộc tính Build Action của tệp GlobalResources.axaml thành AvaloniaResource trong cửa sổ Properties. Sau đó, khai báo như sau:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceInclude Source="avares://DemoApp/Assets/GlobalResources.axaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

3. Truy xuất DataTemplate trong mã C#

Vấn đề cốt lõi là làm thế nào để lấy được đối tượng DataTemplate tên MessageTemplate từ code C#. Chúng ta sẽ thực hiện thông qua App.Current.

Nhiều lập trình viên thường mắc sai lầm khi cố gắng sử dụng bộ chỉ mục (indexer) trực tiếp. Cách làm này thường không hoạt động trong Avalonia và sẽ trả về kết quả null:

// CÁC LÀM SAI - Không sử dụng cách này
var resources = App.Current.Resources;
var template = resources["MessageTemplate"] as IDataTemplate; // Kết quả sẽ là null

Để giải quyết vấn đề này, bạn cần sử dụng phương thức mở rộng TryGetResource. Dưới đây là hàm mẫu thực hiện việc truy xuất đúng cách:

public void RetrieveTemplate()
{
    // Lấy bộ tài nguyên của ứng dụng
    var appResources = Application.Current?.Resources;

    if (appResources != null)
    {
        // Sử dụng TryGetResource để tìm kiếm tài nguyên theo key
        // Tham số theme: null có nghĩa là sử dụng theme hiện tại
        if (appResources.TryGetResource("MessageTemplate", null, out var foundResource))
        {
            if (foundResource is IDataTemplate validTemplate)
            {
                // Bạn đã lấy được đối tượng DataTemplate thành công
                // Có thể sử dụng validTemplate để build control tại đây
                Console.WriteLine("Lấy template thành công.");
            }
        }
    }
}

Phương pháp này đảm bảo bạn kết nối được logic C# với các tài nguyên khai báo trong XAML một cách chính xác, ngay cả khi đang thao tác trong các lớp tách biệt như ViewModel.

Thẻ: avalonia C# XAML DataTemplate mvvm

Đăng vào ngày 21 tháng 6 lúc 17:07