設定控制項中焦點的樣式和 FocusVisualStyle
Windows Presentation Foundation (WPF) 提供了兩種並行機制,以在控制項接收到鍵盤焦點時變更其視覺外觀。 第一種機制是針對套用至控制項的樣式或範本,為 IsKeyboardFocused 等屬性使用屬性 setter。 第二種機制是提供個別的樣式做為 FocusVisualStyle 屬性的值;「焦點視覺化樣式」會針對繪製於控制項上方的提示建立個別的視覺化樹狀結構,而不是藉由取代它來變更控制項或其他 UI 元素的視覺化樹狀結構。 本主題將討論每一種機制的適用案例。
焦點視覺化樣式的用途
焦點視覺化樣式功能提供常見的「物件模型」,以介紹根據鍵盤瀏覽至任何 UI 元素的視覺化使用者回饋。 即使不將新的範本套用至控制項,或是知道特定的範本組合,還是能夠達成此目的。
不過,正因為焦點視覺化樣式功能可以在不知道控制項範本的情況下運作,所以,一定要限制可使用焦點視覺化樣式,針對控制項顯示的視覺化回饋。 此功能真正的運作方式是,在視覺化樹狀結構上方重疊不同的視覺化樹狀結構 (提示),如同由控制項透過其範本的轉譯來建立。 您可以使用會填滿 FocusVisualStyle 屬性的樣式,來建立這個個別的視覺化樹狀結構。
預設的焦點視覺化樣式行為
只有當焦點動作是由鍵盤所起始時,焦點視覺化樣式才會運作。 任何的滑鼠動作或程式設計焦點變更,都會停用焦點視覺化樣式的模式。 如需焦點模式之間差異的詳細資訊,請參閱焦點概觀。
控制項的佈景主題包括預設的焦點視覺化樣式行為,其會成為佈景主題中所有控制項的焦點視覺化樣式。 這個佈景主題樣式是透過靜態索引鍵 FocusVisualStyleKey 的值來識別。 當您在應用程式層級宣告自己的焦點視覺化樣式時,會取代佈景主題的這個預設樣式行為。 或者,如果您定義整個佈景主題,則您應該使用這個相同的索引鍵,針對整個佈景主題定義預設行為的樣式。
在佈景主題中,預設的焦點視覺化樣式通常非常簡單。 以下是一種概略的方式:
<Style x:Key="{x:Static SystemParameters.FocusVisualStyleKey}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
使用焦點視覺化樣式的時機
概念上,套用至控制項的焦點視覺化樣式外觀在各個控制項之間應該保持一致。 確保一致性的方法之一是,只有當您在撰寫整個佈景主題時,才能變更焦點視覺化樣式,而定義於該佈景主題中的每一個控制項都會取得完全相同的焦點視覺化樣式,或是控制項之間視覺上相關之樣式的一些變化。 另外,您可以使用相同的樣式 (或類似樣式),為頁面上或 UI 中每一個可透過鍵盤取得焦點的元素設定樣式。
在不屬於佈景主題的個別控制項樣式上設定 FocusVisualStyle,不是焦點視覺化樣式的預期使用方式。 這是因為控制項之間不一致的視覺化行為,可導致使用者在關於鍵盤焦點方面得到令人困惑的體驗。 如果您想要針對在整個佈景主題中刻意不一致的鍵盤焦點提供控制項特定的行為,更好的方式是在適用於個別輸入狀態屬性的樣式中使用觸發程序,例如 IsFocused 或 IsKeyboardFocused。
焦點視覺化樣式是鍵盤焦點專用的。 因此,焦點視覺化樣式是一種協助工具功能。 如果您想要針對任何類型的焦點進行 UI 變更 (不論是透過滑鼠、鍵盤或程式設計),則您不應該使用焦點視覺化樣式,而應該在從一般焦點屬性 (例如 IsFocused 或 IsKeyboardFocusWithin) 的值運作的樣式或範本中改用 setter 和觸發程序。
建立焦點視覺化樣式的方式
您針對焦點視覺化樣式建立的樣式一律應具備 Control 的 TargetType。 樣式主要應由 ControlTemplate 所組成。 您並未將目標類型指定為將焦點視覺化樣式指派給 FocusVisualStyle 的類型。
因為目標類型一律為 Control,因此您必須使用所有控制項通用的屬性 (使用 Control 類別及其基底類別的屬性) 來設定樣式。 您應該建立將正常運作的範本來與 UI 元素重疊,而且將不會混淆控制項的功能區域。 一般而言,這表示視覺化回饋應該出現在控制項邊界外部,或者做為暫時性或不引人注目的效果,這類效果將不會在套用焦點視覺化樣式的控制項上封鎖點擊測試。 您可以在範本繫結中使用的屬性,這類屬性有助於判斷如何調整重疊範本的大小和位置,包括 ActualHeight、ActualWidth、Margin 和 Padding。
使用焦點視覺化樣式的替代方案
針對不適合使用焦點視覺化樣式的情況 (可能是因為您只設定單一控制項的樣式,或因為您想要對控制項範本有更大的控制權),有許多其他可存取的屬性和技術可用於建立視覺化行為來回應焦點的變更。
如需所有對觸發程序、setter 及事件 setter 的詳細討論,請參閱設定樣式和範本。 路由事件概觀中則會討論如何處理路由事件。
IsKeyboardFocused
若您對鍵盤焦點特別感興趣,可以針對屬性 Trigger 使用 IsKeyboardFocused 相依性屬性。 若要定義非常專屬於單一控制項的鍵盤焦點行為,樣式或範本中的屬性觸發程序是更為合適的技術,而這可能不會以視覺化方式符合其他控制項的鍵盤焦點行為。
另一個類似的相依性屬性是 IsKeyboardFocusWithin,若想要以視覺化方式呼叫的鍵盤焦點位於複合或控制項功能區內的某處,則可能適合使用此屬性。 例如,您可能會放置 IsKeyboardFocusWithin 觸發程序,讓面板以不同的方式分組數個控制項,即使鍵盤焦點可能是更精確地位於該面板中的個別元素上。
您也可以使用事件 GotKeyboardFocus 和 LostKeyboardFocus (以及它們的預覽對等項目)。 您可以使用這些事件做為 EventSetter 的基礎,或者可以在程式碼後置中撰寫事件的處理常式。
其他焦點屬性
如果您希望所有可能變更焦點的原因都會產生視覺化行為,則您應該在 IsFocused 相依性屬性上,或者在用於 EventSetter 的 GotFocus 或 LostFocus 事件上,將 setter 或觸發程序設為基底。