一種自以為是的方式: 本來只是想簡單的做個水印效果,在文本框內容為空的時候提示用戶輸入,這種需求挺常見。網上一搜 都是丟給你你一大段xaml代碼。用c#代碼實現我是不傾向了 既然用wpf就得Xaml啊。首先我想到的是template嘛 wpf到處離不開template 。我想到的是一個border ...
一種自以為是的方式:
本來只是想簡單的做個水印效果,在文本框內容為空的時候提示用戶輸入,這種需求挺常見。網上一搜 都是丟給你你一大段xaml代碼。用c#代碼實現我是不傾向了 既然用wpf就得Xaml啊。首先我想到的是template嘛 wpf到處離不開template 。我想到的是一個border 套一個textblock嘛 然後讓文本內容通過templateBinding到Text嘛 搞得不亦樂乎 ,並且也確實很快就達到了我要的效果:
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" 屬性來達到:
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才能實現:
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>
最終效果: