Thứ bảy, ngày 3 tháng 12 năm 2016

WPF – Control Template

Ngày đăng: 26/3/2012, 8:39:19AM | Lượt xem: 48,182
Hot!

Không giống như Data Template được sử dụng cho các dữ liệu không hiển thị (non-visual), Control Template được sử dụng để tạo nên cấu trúc của các control. Mỗi control đều có một template mặc định. Cấu trúc này bao gồm các thành phần thuộc visual tree nhờ đó tạo ra giao diện cũng như những chức năng mới của control.

Không giống như Data Template được sử dụng cho các dữ liệu không hiển thị (non-visual), Control Template được sử dụng để tạo nên cấu trúc của các control. Mỗi control đều có một template mặc định. Cấu trúc này bao gồm các thành phần thuộc visual tree nhờ đó tạo ra giao diện cũng như những chức năng mới của control.

Tạo ControlTemplate

Mỗi control template được đại diện bằng lớp ControlTemplate. Để thay đổi template của một control, bạn cần gán giá trị cho property Control.Template. Giống như Window, đối tượng ControlTemplate chỉ có thể chứa duy nhất một thành phần con trong nó.

Ví dụ tôi tạo một Ellipse để hiển thị thay cho Button:

<Button>
    <Button.Template>
        <ControlTemplate>
            <Ellipse Fill="Blue" Width="100" Height="100"/>
        </ControlTemplate>
    </Button.Template>
</Button>

Theo ví dụ trên, hình dáng của Button không phải là hình chữ nhật như mặc định mà sẽ có hình tròn (do Width bằng Height). Bạn chỉ có thể tác động đến Button bằng chuột nếu như tọa độ của nó nằm bên trong Ellipse này.

Bạn có thể tách riêng và để ControlTemplate trong phần Resource:

<Window.Resources>
    <ControlTemplate x:Key="template1">
            <Ellipse Fill="Blue" Width="100" Height="100"/>
    </ControlTemplate>
</Window.Resources>

<Button Content="Hello" Template="{StaticResource template1}" />

Hoặc kết hợp với Style bằng cách sử dụng Setter với property Control.Template:

<Window.Resources>
    <ControlTemplate x:Key="template1">
        <Ellipse Fill="Blue" Width="100" Height="100"/>
    </ControlTemplate>
    <Style TargetType="Button">
        <Setter Property="Template" Value="{StaticResource template1}"/>
    </Style>
</Window.Resources>

<Button Content="Hello" />

Template Binding

Đây là kĩ thuật dùng để binding đến các property của đối tượng được áp dụng control template. Chẳng hạn các thành phần con bên trong template có thể binding để lấy các giá trị như kích thước, màu sắc,… của Button để sử dụng và thay đổi theo Button đó.

<ControlTemplate x:Key="template1" TargetType="Button">
    <Ellipse Fill="{TemplateBinding Property=Background}" Width="100" Height="100"/>
</ControlTemplate>

Content Presenter

ContentPresenter là đối tượng dùng để hiển thị nội dung của control (control được áp dụng template gọi là templated parent). Vị trí bạn đặt đối tượng này cũng chính là vị trí mà nội dung của control sử dụng template sẽ xuất hiện. Mặc định đối tượng này chỉ được sử dụng cho ContentControl và lấy giá trị thông qua property ContentControl.Content.

Ví dụ sau tôi tạo một button template và hiển thị dòng chữ “Hello” (từ property Button.Content) vào giữa đối tượng Ellipse:

<Window.Resources>
    <ControlTemplate x:Key="template1" TargetType="Button">
        <Grid>
            <Ellipse Fill="{TemplateBinding Property=Background}"/>
            <ContentPresenter HorizontalAlignment="Center"
                                VerticalAlignment="Center"/>
        </Grid>
    </ControlTemplate>
</Window.Resources>

<Button Width="100" Height="50" Content="Hello"
        Template="{StaticResource template1}" />

Kết quả:

Trong trường hợp không xác định rõ TargetType, bạn cần gán giá trị cho property ContentPresenter.Content thông qua template binding. Ngoài ra với các loại control không thuộc ContentControl, bạn cũng có thể sử dụng cách này. Ví dụ như dùng ContentPresenter để hiển thị nội dung của một TextBox:

<ContentPresenter Content="{TemplateBinding Text}"/>

Control Template Trigger

Giống như Style và Data Template, bạn có thể sử dụng Trigger để thay đổi giá trị property của các thành phần bên trong template. Property mà bạn dùng làm điều kiện được lấy từ templated parent. Trong template, bạn cần đặt tên cho các thành phần và sử dụng property Setter.TargetName để xác định thành phần nào cần thay đổi giá trị của property.

Ví dụ sau tôi tạo một trigger để thay đổi màu văn bản của Button thành White nếu như màu nền là Black:

<Window.Resources>
    <ControlTemplate x:Key="template1" TargetType="Button">
        <Grid>
                <Ellipse Fill="{TemplateBinding Property=Background}"/>
                <ContentPresenter>
                    <ContentPresenter.Content>
                        <TextBlock
                            HorizontalAlignment="Center" VerticalAlignment="Center"
                            Name="textBlock1" Text="{TemplateBinding Content}" />
                    </ContentPresenter.Content>
                </ContentPresenter>
        </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Background" Value="Black">
                    <Setter TargetName="textBlock1" Property="Foreground" Value="White"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
</Window.Resources>

<Button Width="100" Height="50" Content="Hello" Background="Black"
        Template="{StaticResource template1}" />

Xem Style và Control Template mặc định của các Control

Bằng cách sử dụng reflection, bạn có thể dùng lấy được cấu trúc của các control và xem được template mặc định của chúng. Một công cụ hiệu quả cho phép coi style và template của các control dưới dạng mã XAML mà bạn không nên bỏ qua nếu muốn tìm hiểu cách tạo nên các control là StyleSnooper:

http://yinyangit.wordpress.com

Đọc thêm:

 Chia sẻ qua: 
Hot!
Ý kiến bạn đọc

These items will be permanently deleted and cannot be recovered. Are you sure?

Gallery

image

Maecenas viverra rutrum pulvinar

Maecenas viverra rutrum pulvinar! Aenean vehicula nulla sit amet metus aliquam et malesuada risus aliquet. Vestibulum rhoncus, dolor sit amet venenatis porta, metus purus sagittis nisl, sodales volutpat elit lorem…

Read more

Text Links

Thiết kế logo chuyên nghiệp Insky
DAFABET
W88 w88b.com/dang-ky-tai-khoan-w88
W88
Copyright © 2011 - 2012 vietshare.vn by phamkhuong102@gmail.com doanhkisi2315@gmail.com. All rights reserved.