2017-01-11 24 views
1

我有一個自定義的文本框控件,我想在某個屬性爲true時繪製水平線,然後在屬性爲false時刪除線條。該線需要具有控制寬度的-2的寬度並且距控制底部的高度爲-5。我目前使用的有以下OnRenderAdorner來完成此行爲:如何使用自定義樣式觸發器在TextBox控件中繪製線條

protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) 
{ 
    base.OnRender(drawingContext); 

    var rect = new Rect(AdornedElement.RenderSize); 
    rect.Inflate(-2, -5); 

    // ColoredPen is a custom class that holds a Pen object 
    drawingContext.DrawLine(ColoredPen.Pen, rect.BottomLeft, rect.BottomRight); 
} 

我遇到了一些問題,其中裝飾器沒有正確刷新,所以它消失,即使相關的屬性是true。我嘗試了幾種不同的方法來確保Adorner被刷新,但是它失敗了。我相信Adorner方法並不是真正解決我的問題的方法。我認爲如果我用ControlTemplate這個屬性作爲觸發器會更好。舉個簡單的例子,我們可以使用IsFocused屬性。這是迄今爲止的代碼,但我不確定如何設置Line的X和Y屬性,以及如何設置它的工作方式。這個當前的代碼只是使應用程序崩潰(是的,我知道這個代碼中設置的行的尺寸並不是我想要的,這是我試圖讓行顯示,我想我可以從那裏調整它)。

<Style x:Key="TextBoxUnderlineTemplate" TargetType="myUi:MyTextBox"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="myUi:MyTextBox"> 
       <Line Name="UnderlineStuff" Stroke="Black" X1="0" 
        X2="{Binding RelativeSource={RelativeSource Self}, Path=Width}" 
        Y1="{Binding RelativeSource={RelativeSource Self}, Path=Height}" 
        Y2="{Binding RelativeSource={RelativeSource Self}, Path=Height}" 
        StrokeThickness="2" Visibility="Collapsed"/> 
       <ControlTemplate.Triggers> 
        <Trigger Property="IsFocused" Value="True"> 
         <Setter TargetName="UnderlineStuff" Property="Visibility" Value="Visible"/> 
        </Trigger> 
       </ControlTemplate.Triggers> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

所以,我正在尋找一種方法,使一個控件模板這項工作,或者如果有,如何使這項工作另一項建議,那也將是可以接受的(裝飾器是出)。請注意,一旦這個工作,我將需要能夠添加一個比這條線稍低的第二條線,這取決於一個額外的屬性。

回答

1

這在IsMouseOver上表示下劃線。您可能需要提高非常簡單的轉換實現,它是基於字體大小:

enter image description here

XAML:

<Window x:Class="WpfApplication363.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:WpfApplication363" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="300" Width="300"> 

<Window.Resources> 

    <local:MyConverter x:Key="conv1"/> 

    <SolidColorBrush x:Key="TextBox.Static.Border" Color="#FFABAdB3"/> 
    <SolidColorBrush x:Key="TextBox.MouseOver.Border" Color="#FF7EB4EA"/> 
    <SolidColorBrush x:Key="TextBox.Focus.Border" Color="#FF569DE5"/> 

    <Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}"> 
     <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 
     <Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/> 
     <Setter Property="HorizontalContentAlignment" Value="Left"/> 
     <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
     <Setter Property="AllowDrop" Value="true"/> 
     <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> 
     <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type TextBox}"> 
        <Grid> 
         <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"> 
          <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/> 
         </Border> 
         <Line x:Name="line1" 
           Y1="{TemplateBinding FontSize, Converter={StaticResource conv1}}" 
           X2="{Binding ElementName=border, Path=ActualWidth}" 
           Y2="{TemplateBinding FontSize, Converter={StaticResource conv1}}" 
           Stroke="Red" 
           Visibility="Hidden"/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Opacity" TargetName="border" Value="0.56"/> 
         </Trigger> 
         <Trigger Property="IsMouseOver" Value="true"> 
          <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/> 
          <Setter Property="Visibility" TargetName="line1" Value="Visible"/> 
         </Trigger> 
         <Trigger Property="IsKeyboardFocused" Value="true"> 
          <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Style.Triggers> 
      <MultiTrigger> 
       <MultiTrigger.Conditions> 
        <Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/> 
        <Condition Property="IsSelectionActive" Value="false"/> 
       </MultiTrigger.Conditions> 
       <Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/> 
      </MultiTrigger> 
     </Style.Triggers> 
    </Style> 

</Window.Resources> 

<Grid> 

    <TextBox Style="{DynamicResource TextBoxStyle1}" 
      HorizontalAlignment="Center" 
      VerticalAlignment="Center" 
      FontSize="24" 
      Text="Textbox with underline !"/> 

</Grid> 

轉換器:

public class MyConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     return ((double)value) + 4; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

我還沒有嘗試過,但看起來很有希望。 「Border」和「ScrollViewer」的用途是什麼?其次,我是否需要在模板中添加所有這些額外的'Setters',還是可以將它們排除?在我的應用程序中,我正在根據應用程序中的事件更改對齊方式,字體大小,顏色和其他內容。 – pstrjds

+0

'Border','ScrollViewer'和'Setters'都是默認樣式的一部分。與任何'Style'一樣,您可以自定義它,添加和/或從中刪除,只要它不會違反任何您需要的默認行爲或功能。 – jsanalytics

相關問題