1. 程式人生 > >WPF屬性(二)附加屬性

WPF屬性(二)附加屬性

rop max main 包裝 ssa sha 框架 message 作用

原文:WPF屬性(二)附加屬性

附加屬性是說一個屬性本來不屬於某個對象,但由於某種需求而被後來附加上,也就是把對象放入一個特定環境後對象才具有的屬性就稱為附加屬性,附加屬性的作用就是將屬性與數據類型解耦,讓數據類型的設計更加靈活,舉例,一個TextBox被放在不同的布局容器中時就會有不同的布局屬性,這些屬性就是由布局容器為TextBox附加上的,附加屬性的本質就是依賴屬性,二者僅僅在註冊和包裝器上有一點區別

小技巧,在VS中輸入propa後,連按兩次tab鍵,可以添加好一個附加屬性的框架,繼續按tab鍵,可以繼續修改附加屬性的內容


舉個例子,Person這個類,放在學校中就會獲得年級這個屬性,那麽準備一個School類,School類繼承DependencyObject,定義一個附加屬性

    public class School : DependencyObject
    {
        public static int GetGrade(DependencyObject obj)
        {
            return (int)obj.GetValue(GradeProperty);
        }

        public static void SetGrade(DependencyObject obj, int value)
        {
            obj.SetValue(GradeProperty, value);
        }

        public static readonly DependencyProperty GradeProperty =
            DependencyProperty.RegisterAttached("Grade", typeof(int), typeof(School), new UIPropertyMetadata(0));
    }

可以看到,附加屬性已依賴屬性有兩點不同:

一。附加屬性使用的RegisterAttached方法,而依賴屬性使用的是Register方法

二。附加屬性使用兩個方法進行包裝,依賴屬性使用CLR屬性對GetValue和SetValue兩個方法進行包裝

如何使用School的GradeProperty呢,首先準備一個DependencyObject的派生類Human

    public class Human : DependencyObject
    {

    }

使用這個附加屬性

            Human human = new Human();
            School.SetGrade(human, 6);
            MessageBox.Show(School.GetGrade(human).ToString());
看看實例代碼,如果要在一個3行3列的表格布局的最中間一格放置一個按鈕,界面代碼如下:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Button Grid.Row="1" Grid.Column="1" Content="OK" />
    </Grid>
</Window>

運行後效果如圖:

技術分享圖片

那麽,如果用C#代碼來實現這個效果,代碼如下:

            Grid grid = new Grid() { ShowGridLines = true };
            grid.RowDefinitions.Add(new RowDefinition());
            grid.RowDefinitions.Add(new RowDefinition());
            grid.RowDefinitions.Add(new RowDefinition());

            grid.ColumnDefinitions.Add(new ColumnDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());
            grid.ColumnDefinitions.Add(new ColumnDefinition());

            Button button = new Button() { Content = "OK" };
            Grid.SetRow(button, 1);
            Grid.SetColumn(button, 1);

            grid.Children.Add(button);
            Content = grid;

效果與上圖一致,附加屬性的用法很奇怪吧,附加屬性同時也是依賴屬性,再附上一個例子,用兩個滑塊分別控制按鈕在九宮格中的位置

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="420" Width="525">
    <StackPanel>
        <Grid ShowGridLines="True" Height="300">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition />
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <Button Content="OK" Grid.Row="{Binding ElementName=slider1, Path=Value}" Grid.Column="{Binding ElementName=slider2, Path=Value}" />
        </Grid>
        <Slider x:Name="slider1" Minimum="0" Maximum="2" />
        <Slider x:Name="slider2" Minimum="0" Maximum="2" />
    </StackPanel>
</Window>


WPF屬性(二)附加屬性