2000條你應知的WPF小姿勢 基礎篇<57-62 依賴屬性進階>


  在正文開始之前需要介紹一個人:Sean Sexton. 來自明尼蘇達雙城的軟件工程師。最為出色的是他維護了兩個博客:2,000Things You Should Know About C#  和 2,000 Things You Should Know About WPF 。他以類似微博式的150字簡短語言來每天更新一條WPF和C#重要又容易被遺忘的知識。Follow他的博客也有一段日子了,很希望能夠分享給大家。

  本系列我不僅會翻譯他的每一個tip,也會加入自己開發之中的看法和見解。本系列我希望自己也能和他一樣堅持下來,每天的進步才能促成偉大。

  在這里鄭重說明.該系列是基於Sean Sexton先生的英文博客, Sean Sexton擁有全部版權和撤銷權利。

 

  前文:<1-7> , <8-14>,<15-21>22-27>, <28-33>,<34-39>,<40-44>,<45-50>

 

  [小九的學堂,致力於以平凡的語言描述不平凡的技術。如要轉載,請注明來源:小九的學堂cnblogs.com/xfuture]


  #57 依賴屬性值變化時的通知事件

  當一個依賴屬性值改變的時候,實現它的類可以隨時得知其改變。當該類注冊該依賴屬性的時候可以指定PropertyChangedCallback來獲取其事件。

  

PropertyMetadata ageMetadata =
    new PropertyMetadata(
        18,     // Default value
        new PropertyChangedCallback(OnAgeChanged),   // ** call when property changes
        new CoerceValueCallback(OnAgeCoerceValue));
 
// Register the property
AgeProperty =
    DependencyProperty.Register(
        "Age",                 // Property's name
        typeof(int),           // Property's type
        typeof(Person),        // Defining class' type
        ageMetadata,           // Defines default value & callbacks  (optional)
        new ValidateValueCallback(OnAgeValidateValue));   // validation (optional)

  該類可以通過回調的函數才處理當值改變時候的邏輯。比如通過一個值的改變影響另一個值。

  

private static void OnAgeChanged
    (DependencyObject depObj, DependencyPropertyChangedEventArgs e)
{
    Person p = (Person)depObj;
    p.AARPCandidate = (int)e.NewValue > 60 ? true : false;
}

 

  #58 驗證依賴屬性

  注冊依賴屬性時,可以進行驗證回調。當依賴屬性被指定一個新值得時候,可以先通過驗證函數驗證,返回true or false來表示其是否有效。當注冊這個依賴屬性的時候可以指定其驗證回調函數。

  

AgeProperty =
    DependencyProperty.Register(
        "Age",                 // Property's name
        typeof(int),           // Property's type
        typeof(Person),        // Defining class' type
        ageMetadata,           // Defines default value & changed/coercion callbacks  (optional)
        new ValidateValueCallback(OnAgeValidateValue));   // *** validation (optional)

  驗證回調函數可以對新值進行驗證

  

private static bool OnAgeValidateValue (object value)
{
    int age = (int) value;
 
    // Only allow reasonable ages
    return (age > 0) && (age < 120);
}

  如果值不能被接受,則拋出exception

  

Person p = new Person("Samuel", "Clemens");
p.Age = 40;     // ok
p.Age = 300;    // throws System.ArgumentException

  

 

  #59 強制改變依賴屬性值

  人在做事的時候,都需要考慮一個底線,很多時候做了過分的事情你就期望有人提醒你,“嗨,這個事情你越線了!”。依賴屬性就有一個特性,可以在你越線的時候把你拉回底線。那就是CoerceValueCallback。當你apple新的value的時候,它是最后一層安全系數。

  你可以在定義這個依賴屬性的時候,定義CoerceValueCallback.

  

PropertyMetadata ageMetadata =
    new PropertyMetadata(
        18,     // Default value
        new PropertyChangedCallback(OnAgeChanged),
        new CoerceValueCallback(OnAgeCoerceValue));    // ** allow class to coerce value
 
// Register the property
AgeProperty =
    DependencyProperty.Register(
        "Age",                 // Property's name
        typeof(int),           // Property's type
        typeof(Person),        // Defining class' type
        ageMetadata,           // Defines default value & changed/coercion callbacks  (optional)
        new ValidateValueCallback(OnAgeValidateValue));   // validation (optional)

  你可以在delegate的OnAgeCoerceValue方法里來控制它的界限,並給予其新值。

  

private static object OnAgeCoerceValue
    (DependencyObject depObj, object baseValue)
{
    int coercedValue = (int)baseValue;
 
    if ((int)baseValue > 120)
        coercedValue = 120;
 
    if ((int)baseValue < 1)
        coercedValue = 1;
 
    return coercedValue;
}

 

  #60 Wpf中基於依賴屬性特性實現的一個例子

  依賴屬性有三種回調函數類可以來進行控制:

  1. PropertyChangedCallback 當獲取一個新值得時候觸發

  2. ValidateValueCallback 決定值是否有效

  3. CoerceValueCallback 強制更改為其他值

  

  DataGrid.FrozenColumnCount是一個三種邏輯都實現了的例子。

  1. PropertyChangedCallback. 渲染標題的時候,使之能正確顯示。

  2. ValidateValueCallback 驗證是否為負值。

  3. CoerceValueCallback 如果賦予的值大於其行數,則強制為最大值。

 

  #61 響應變化

  在WPF編程中對依賴屬性除了使用PropertyChangedCallback事件來進行響應變化,還有其他方式。

  有兩種方式可以做到:

  1. Data Binding

  2. Triggers

 

  #62 Triggers

  下面介紹Triggers。可以通過觸發器Triggers來響應值變化時引起的蝴蝶效應。

  由於觸發器只能針對離散值。所以下面的例子是簡單的布爾值關聯的觸發器Trigger

  

<CheckBox Content="Check Me" HorizontalAlignment="Center">
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Style.Triggers>
                <Trigger Property="IsChecked" Value="true">
                    <Setter Property="Foreground" Value="BlueViolet"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </CheckBox.Style>
</CheckBox>

  但該checkbox選中的時候,字體會被觸發更改為BlueViolet.這邊是trigger實現值變化時蝴蝶效應的方法。

  

  

  而且Triggers是不需要在后台代碼中寫任何code的。只需要在xaml中就可以實現邏輯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM