程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 《Programming WPF》翻譯 第5章 7.控件模板

《Programming WPF》翻譯 第5章 7.控件模板

編輯:關於.NET

如果仔細的看我們當前的TTT游戲,會發現Button對象並沒有完全為我們工作 。哪些TTT面板有內圓角?

圖5-14

這裡,我們真正需要的是能夠保持按鈕的行為,如支持內容和點擊事件,但 是我們想要接管這些按鈕的外觀。WPF允許這種方式,因為內在的控件創建的時 候是缺少外觀性的,例如,他們提供行為,但是外觀可以被完全包裝在客戶端控 件的外面。

還記得我們是如何使用數據模板,來為非可視化對象提供外觀的麼?我們能 夠使用控件模板對控件做同樣的事情,這將是一組StoryBoard,觸發器,以及大 多數重要的提供控件外觀的元素。

為了修復我們的按鈕外觀,我們創建了一個控件模板的資源。讓我們從示例 5-31出發,這是一個帶有簡單的矩形,和以後考慮如何顯示實際的按鈕內容。

示例5-31

<Window.Resources>
  <ControlTemplate x:Key="ButtonTemplate">
    <Rectangle />
  </ControlTemplate>

  <!-- let's just try one button for now -->
  <Button Template="{StaticResource ButtonTemplate}"  />

</Window.Resources>

圖5-15顯示了設置一個單獨按鈕的Template屬性的結果。

注意到按鈕過去樣子的痕跡(保留在圖5-15中)。不幸的是,看不到我們的 矩形的痕跡。問題在於,缺少一個顯示的填充設置,這個矩形的默認填充是透明 的,顯示grid的黑色背景。讓我們將其設置為喜歡的萬聖節顏色:

<ControlTemplate x:Key=”ButtonTemplate”>
            <Rectangle Fill=”Orange” />
</ControlTemplate>

圖5-15

現在我們在這個地方,如圖5-16所示。

圖5-16

注意,拐角處是如何成直角的?而且,一旦你點擊了按鈕,你不會獲得壓下 的效果。(而且我沒有意味“一個不爽的感覺”)

5.7.1控件模板和樣式

注意到我們在控件模板上取得的一些成果,讓我們將其復制到其它按鈕上。 我們可以手動設置每個按鈕上的模板屬性,或者,作為最普通的,我們可以用按 鈕的樣式包裝這個模板控件。如示例5-32。

示例5-32

<Window.Resources>
  <Style TargetType="{x:Type Button}">

    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate>
          <Rectangle Fill="Orange" />
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>

</Window.Resources>

<!-- No need to set the Template property for each button -->
<Button  x:Name="cell00" />

正如示例5-32所示,模板屬性和使用樣式設置是一樣的。圖5-17顯示了結果 。

圖5-17

仍然,橙色是不和諧的,尤其是因為白色背景樣式上的設定。我們可以用模 板綁定來解決這個問題。

5.7.2模板綁定

為了回到我們的白色按鈕,我們可以硬編碼將矩形填充為白色,但是如果樣 式要改變它呢(正如在我們中斷的動畫)?取代以硬編碼填充矩形,我們使用模 板綁定來將模板應用到控件屬性中,正如示例5-33所示。

示例5-33

<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="White" />

  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate x:Key="ButtonTemplate">
        <Rectangle Fill="{TemplateBinding Property=Background}" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>

</Style>

模板綁定就像數據綁定,除了綁定的屬性來自被你替換了模板的控件(稱為 模板化的父級別)。在我們的情形中,像Background, HorizontalContentAlignment等等,是美麗的游戲,用來模板綁定自父級別。同 時,像數據綁定,模板綁定是相當小巧的——用來保持模板中的條目屬性是最新 的,隨著外界的屬性改變,如被樣式和動畫設置等等。舉例來說,圖5-18顯示了 混淆矩形的Fill屬性到按鈕的Background屬性的效果——仍然適當地通過我們的 點擊動畫和鼠標盤旋的行為。

圖5-18

盡管如此,我們還沒有徹底到達。如果我們將要改變圖畫樣品,這樣圖5-18 已經變為了一個可玩的游戲,我們不得不顯示所有的移動。為了這麼做,我們需 要一個內容推薦者。

5.7.3內容推薦者

如果你曾經被廣告牌或汽車站長椅上寫著的“這裡是你的廣告!”所驅動, 然後這就是所有你需要知道的理解內容推薦者。內容推薦者等價於WPF中的“這 裡是你的內容”,允許內容由插入的ContentContainer控件保持在運行期。

在我們的情形中,內容是可視化的PlayerMove對象。取代以復制所有的工作 到按鈕新的控件模板中,我們只想要去除它在正確的地方。內容推薦者的工作是 獲取內容——由內容模板化的父級別提供,以及所有必須要顯示的事物,包括樣 式,觸發器等等。內容推薦者可以添加到你的模板中——無論在哪裡看到的模板 (包括多次,如果它使你愉快,例如生成一個下拉陰影)。在我們的情形中,我 們在示例5-34中組成一個內容推薦者,使用第2章的技術在grid中放一個矩形。

示例5-34

<Style TargetType="{x:Type Button}">
  <Setter Property="Background" Value="White" />

  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate>
        <Grid>
          <Rectangle Fill="{TemplateBinding Property=Background}" />
          <ContentPresenter
            Content="{TemplateBinding Property=ContentControl.Content}" />
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>

</Style>

在示例5-34中,內容推薦者的Content屬性綁定到ContentControl.Content屬 性,為了內容成功使用。作為使用樣式,我們可以避免給模板綁定屬性名稱加上 類的前綴,通過在ContentTemplate元素上設置TargetAttribute屬性。

    <ControlTemplate TargetType="{x:Type Button}">
      <Grid>
        <Rectangle Fill="{TemplateBinding Property=Background}" />
        <ContentPresenter
          Content="{TemplateBinding Property=Content}" />
      </Grid>
    </ControlTemplate>

進一步,在恰當的位置使用TargetType屬性,你可以一起去除顯示地模板綁 定到Content,屬性上,同時它會進行自動設置。

    <ControlTemplate TargetType="{x:Type Button}">
      <Grid>
        <Rectangle Fill="{TemplateBinding Property=Background}" />
        <!-- with TargetType set, the template binding for the -->
        <!-- Content property is no longer required -- >
        <ContentPresenter />
      </Grid>
    </ControlTemplate>

內容推薦者是我們需要的全部,使得我們的游戲回到具有功能性,正如圖5- 19所示。

圖5-19

5.7.4真實的工作

最後一小塊工作是獲取右間隙。由於內容推薦者沒有自身的Padding屬性,我 們不能直接綁定Padding屬性(它也沒有Background屬性,這是為什麼我們使用 Rectangle和其Fill屬性)。因為這些屬性並不匹配內容推薦者,你不得不找到 映射或者組合提供這些功能的元素。例如,padding是控件中一定數量的空白, 另一方面,Margin是控件周圍一定數量的空白。由於他們都是同樣的類型, System.Windows.Thickness,如果我們可以映射按鈕中的Padding到內容控件的 外面。我們的TTT游戲看起來就會很漂亮:

    <Style TargetType="{x:Type Button}">
      <Setter Property="Background" Value="White" />
      <Setter Property="Padding" Value="10,5" />

      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="{x:Type Button}">
            <Grid>
              <Rectangle Fill="{TemplateBinding Property=Background}" />
              <ContentPresenter
                Content="{TemplateBinding Property=Content}"
                Margin="{TemplateBinding Property=Padding}" />
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>

    </Style>

圖5-20顯示了我們最終的TTT變體。

圖5-20

就像Padding和Margin間的映射,建立一個元素提供給你想要的外觀,並且從 父級別的模板綁定到相應的屬性,將要做很多的工作來創建你自己的控件模板。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved