WPF的TextBox水印效果詳解

一種自覺得是的方式:

原本只是想簡單的作個水印效果,在文本框內容爲空的時候提示用戶輸入,這種需求挺常見。網上一搜 都是丟給你你一大段xaml代碼。用c#代碼實現我是不傾向了 既然用wpf就得Xaml啊。首先我想到的是template嘛 wpf處處離不開template 。我想到的是一個border 套一個textblock嘛 而後讓文本內容經過templateBinding到Text嘛 搞得不亦樂乎 ,而且也確實很快就達到了我要的效果:c#

 1 <TextBox>
 2     <TextBox.Template>
 3         <ControlTemplate TargetType="TextBox">
 4             <Border BorderThickness="1" Name="border" BorderBrush="Red">
 5                 <TextBlock Text="{TemplateBinding Text}"></TextBlock>
 6             </Border>
 7             <ControlTemplate.Triggers>
 8                 <MultiTrigger>
 9                     <MultiTrigger.Conditions>
10                         <Condition Property="Text" Value=""></Condition>
11                     </MultiTrigger.Conditions>
12                     <Setter Property="Background" TargetName="border">
13                         <Setter.Value>
14                             <VisualBrush AlignmentX="Left" AlignmentY="Top"  Stretch="None">
15                                 <VisualBrush.Visual>
16                                     <TextBlock Width="500" Height="100" Background="#FFE8DBDB">請輸入內容22</TextBlock>
17                                 </VisualBrush.Visual>
18                             </VisualBrush>
19                         </Setter.Value>
20                     </Setter>
21                 </MultiTrigger>
22             </ControlTemplate.Triggers>
23         </ControlTemplate>
24     </TextBox.Template>
25 </TextBox>

最後仔細一看杯具的發現文本內容輸入的時候沒有光標,而後我想到的就是把模板裏的textblock改成textbox就完了嘛。好 一改更杯具了 水印效果抽風了 最後發現 用c#代碼 強制讓文本框Focus() 貌似就能夠 ,也許自己元素就是TextBox 模板裏面 再放TextBox 就會致使焦點沒法獲取形成各類混亂吧。最後弄很差 。編碼

經過嘗試更改TextBox自帶的模板來達到效果

導出系統默認textBox的模板visualTree ,通過嘗試成功達到效果,值得一提的是 我納悶兒網上那些人爲甚有的一貼出的xaml代碼裏面就是scrollviewer呢 而且還可以正確運行 讓我很難理解 ,一看原來系統默認的就是scrollviewer 原來如此 還有Name=PART_ContentHost  只要寫成他天然而然就能被當初內容宿主處理。看來PART_ContentHost  是個很特殊的系統名稱,還有就是多行文本框經過 設置AcceptsReturn="True" VerticalScrollBarVisibility="Auto" 屬性來達到:spa

 1  
 2 <TextBox Text="" Height="60" Name="nihao" Width="300" AcceptsReturn="True" VerticalScrollBarVisibility="Auto"  >
 3     <TextBox.Template>
 4         <ControlTemplate TargetType="TextBox">
 5             <!--下面必須寫成PART_ContentHost 才能正常 無語又是一個神祕硬編碼 
 6                         我就納悶兒 爲甚網上的人要寫 scrollviewer 並且天然而然的就成了宿主 讓文本顯示在裏面
 7                         原來經過代碼導出的默認的visualtree就是這樣的。只有decorator 或scrollviewer元素能夠用做PART_ContentHost
 8                         -->
 9             <Border Name="borderContent" CornerRadius="10 0 0 10"  BorderThickness="1" BorderBrush="Blue" Background="#FFE8DBDB"  SnapsToDevicePixels="True">
10                 <ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Name="PART_ContentHost" Focusable="False"/>
11             </Border>
12             <ControlTemplate.Triggers>
13                 <MultiTrigger >
14                     <MultiTrigger.Conditions>
15                         <Condition Property="IsFocused" Value="False"/>
16                         <Condition Property="Text" Value=""/>
17                     </MultiTrigger.Conditions>
18                     <Setter Property="Background" TargetName="borderContent" >
19                         <Setter.Value>
20                             <VisualBrush AlignmentX="Left" AlignmentY="Top"  Stretch="None">
21                                 <VisualBrush.Visual>
22                                     <!--這裏是不管何種手段都沒法取得父元素 的寬度我無語 因此只能儘可能把寬度 高度往大了寫
23                                                 {Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Width}
24                                                 -->
25                                     <TextBlock Width="500" Height="100" Background="#FFE8DBDB">請輸入內容</TextBlock>
26                                 </VisualBrush.Visual>
27                             </VisualBrush>
28                         </Setter.Value>
29                     </Setter>
30                 </MultiTrigger>
31                 <Trigger Property="IsFocused" Value="True">
32                     <Setter Property="Background" TargetName="borderContent" Value="#FFE8DBDB"></Setter>
33                 </Trigger>
34             </ControlTemplate.Triggers>
35         </ControlTemplate>
36     </TextBox.Template>
37 </TextBox>
38             

另外一種方式:

還有一種方式就是直接控制外圍的style trigger也可達到效果,只不過圓角border你必需要在text控件外再套border才能實現:code

 1  
 2 <TextBox Text="" Height="30" BorderThickness="1" BorderBrush="Blue"  Margin="10">
 3     <TextBox.Style>
 4         <Style TargetType="TextBox">
 5             <!--這種方式直接控制外圍的 background 也能夠達到效果 ,只不過圓角邊框不能實現-->
 6             <Setter Property="Background" Value="#FFE8DBDB"></Setter>
 7             <Style.Triggers>
 8                 <MultiTrigger>
 9                     <MultiTrigger.Conditions>
10                         <Condition Property="Text" Value="" ></Condition>
11                     </MultiTrigger.Conditions>
12                     <Setter Property="Background" >
13                         <Setter.Value>
14                             <VisualBrush AlignmentX="Left" AlignmentY="Top"  Stretch="None" >
15                                 <VisualBrush.Visual >
16                                     <Border Background="#FFE8DBDB" Width="500" Height="100">
17                                         <TextBlock >請輸入內容</TextBlock>
18                                     </Border>
19                                 </VisualBrush.Visual>
20                             </VisualBrush>
21                         </Setter.Value>
22                     </Setter>
23                 </MultiTrigger>
24             </Style.Triggers>
25         </Style>
26     </TextBox.Style>
27 </TextBox>

最終效果:blog

相關文章
相關標籤/搜索