WPF – Sự Khác Nhau Giữa StaticResource với DynamicResource Trong WPF

Về khía cạnh náo đó chúng ta sẽ thấy giữa StaticResource và DynamicResource không có nhiều sự khác biệt và chúng có thể thay thế lẫn nhau mà không có vấn đề gì. Tuy vậy, ở một khía cạnh khác việc dùng chúng không đúng mục đích là hết sức nguy hiểm.

StaticResource và DynamicResource

Giống nhau:

WPF giới thiệu một khái niệm rất tiện dụng: Khả năng lưu trữ dữ liệu/thông tin như một nguồn tài nguyên(Resource) cho một/một số Control hay cho Windows/Page hoặc cho toàn bộ ứng dụng. Các dữ liệu có thể được lưu trữ dưới nhiều dạng(Type) khác nhau và trong WPF chúng ta thường thấy nó khi các Style/Template được định nghĩa. Điều này cho phép bạn đặt dữ liệu ở một nơi và sau đó sử dụng nó từ hoặc một nơi khác một cách đơn giản.

Tôi xét đến một ví dụ như sau:

<Window x:Class="WPF_Application.ResourceSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        Title="ResourceSample" Height="150" Width="350">
    <Window.Resources>
        <!-- Tôi định nghĩa một chuỗi trong Window.Resources -->
        <sys:String x:Key="strHelloWorld">Hello, world!</sys:String>
    </Window.Resources>

    <StackPanel Margin="10">
        <!-- Và tôi sử dụng nó ở đây StaticResource-->
        <TextBlock Text="{StaticResource strHelloWorld}" FontSize="56" 

        <!-- Và tôi sử dụng nó ở đây DynamicResource-->
        <TextBlock Text="{DynamicResource  strHelloWorld}" FontSize="56"
    </StackPanel>
</Window>

Và chúng ta có cùng một kết quả:

StaticResource và DynamicResource tuanphamdg

Khác nhau:

  1. Nếu dùng StaticResource bạn sẽ thấy nó giống với cách dùng Constant trong các ngôn ngữ lập trình cấp cao – có nghĩa là nó sẽ được loading một lần duy nhất để xử lý, việc bạn thay đồi giá trị của “Resource” sau đó đều không có ý nghĩa. Nếu dùng DynamicResource thì ngược lại, bạn có thể thay đổi giá trị của “Resource” để thay đổi thông tin nơi reference nó.
  2. Nếu dùng StaticResource chúng ta sẽ phải gặp rắc rối khi “Resource” đang được reference lại không tồn tại. Với DynamicResource thì nếu đối tượng được reference không tồn tại nó sẽ có giá trị default(Việc này có thể sẩy ra vì lúc bạn Building Project sẽ không hề nhận được thông báo lỗi ‘Resource not found‘)
  3. Khi bạn dùng DynamicResource bạn sẽ phải tốn nhiều chi phí hơn, giảm hiệu xuất ứng dụng, ý (1) cũng cho thấy điều đó.

Minh chứng:

Sample.XAML

<Window x:Class="WpfDynamicStaticResource.MainWindow" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
Title="MainWindow" Height="140" Width="425">
    <Window.Resources>
        <SolidColorBrush x:Key="WindowBrush" Color="Red"/>
        <Style TargetType="{x:Type TextBox}" x:Key="Text">
            <Setter Property="MinWidth" Value="200" />
            <Setter Property="Margin" Value="5" />
            <Setter Property="HorizontalAlignment" Value="Right" />
        </Style>
    </Window.Resources>        
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/> <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>         
        </Grid.RowDefinitions>
        <TextBlock Margin="7" Grid.Row="0"  Foreground="{StaticResource WindowBrush}">
        User Name:</TextBlock>
        <TextBox Name="txtUserName" Style="{StaticResource Text }" Margin="5" 
        Grid.Row="0" Grid.Column="1" />
        <TextBlock Margin="7" Grid.Row="1" Foreground="{DynamicResource WindowBrush}">
        Password:</TextBlock>
        <TextBox Name="txtPassword" Margin="5" Style="{DynamicResource Text }" 
        Grid.Row="1" Grid.Column="1" />        
        <StackPanel Grid.Row="3" Grid.ColumnSpan="2" Orientation="Horizontal" 
        HorizontalAlignment="Center">
            <Button Margin="7" Name="btnBlack" MinWidth="100" Click="btnBlack_Click">
        Black</Button>
            <Button Margin="7" Name="btnRed" MinWidth="100" Click="btnRed_Click">Red
        </Button>
        </StackPanel>
    </Grid>
</Window>

Sample.CS

public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();            
        }
 
        private void btnBlack_Click(object sender, RoutedEventArgs e)
        {
            Brush blackBrush = new SolidColorBrush { Color = Colors.Black };
            this.Resources["WindowBrush"] = blackBrush;            
        }
 
        private void btnRed_Click(object sender, RoutedEventArgs e)
        {
            Brush blackBrush = new SolidColorBrush { Color = Colors.Red };
            this.Resources["WindowBrush"] = blackBrush;
        }  
    }

Lời khuyên:

Nên cân nhắc việc dùng  StaticResource và DynamicResource

Các StaticResource luôn được load lên trước và chúng sẽ ready khi ứng dụng đã Start vì thế ứng dụng của bạn sẽ khởi động rất lâu nếu dữ liệu Static là phức tạp và quá lớn.

Nếu bạn dùng DynamicResource thì hiệu xuất ứng dụng sẽ giảm đi đáng kể nhưng bạn lại có thể thay đổi giá trị của Resource lúc Runtime – cái mà StaticResource không làm được.

Hi vọng các bạn sẽ có cái nhìn rõ ràng hơn về StaticResource và DynamicResource, chúc các bạn thành công!
Phạm Tuân

Advertisements

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s