2013-11-29 50 views
1

我需要在WPF中創建自定義文本框和文本框將有一些數字和字符串「%每年」像「55%每年」。用戶應該只能改變文本框中的數字,我想保持字符串「%Per Annum」不可編輯。請幫幫我。自定義文本框與固定內容的一部分

+1

這聽起來像一個漂亮的非標準用戶界面,因此(相對)昂貴。單位能否以更平臺標準的方式生活在文本框之外? –

回答

1

在WPF中,您可以修改控件的模板以在保持功能的同時完全改變外觀。在您的情況下,您可以通過在控件邊框內添加一些額外的文本來修改TextBox的控件模板。

在Visual Studio中,向您的XAML添加一個TextBox。然後在文檔大綱你可以右鍵點擊該TextBox並選擇編輯模板 =>編輯副本...。然後將一個StyleTextBox添加到您的XAML中,其中包含默認TextBox使用的ControlTemplate的副本。然後,您可以隨意修改模板。

TextBox的主要部分是ListBoxChrome邊界內的ScrollViewer。爲了得到你想要的結果,你可以用兩列將ScrollViewer包裝在一個Grid中,然後在第二列中放置帶有文本「%Per Annum」的TextBlock。您可能還想要對齊TextBox中的文本,並且默認情況下可以通過將HorizontalContentAlignment設置爲Right,TextBoxStyle來實現。

這裏就是我增加了一些意見,看看在那裏我所做的編輯一個完整的示例XAML:

<Window 
    x:Class="WpfApplication.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" 
    Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
    <LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0"> 
     <GradientStop Color="#ABADB3" Offset="0.05"/> 
     <GradientStop Color="#E2E3EA" Offset="0.07"/> 
     <GradientStop Color="#E3E9EF" Offset="1"/> 
    </LinearGradientBrush> 
    <Style x:Key="PerAnnumTextBoxStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}"> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 
     <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="Padding" Value="1"/> 
     <Setter Property="AllowDrop" Value="true"/> 
     <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 
     <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> 
     <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> 
     <!-- New setter --> 
     <Setter Property="HorizontalContentAlignment" Value="Right"/> 
     <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type TextBox}"> 
      <Themes:ListBoxChrome x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true"> 
       <!-- ScrollViewer wrapped in a Grid --> 
       <Grid> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition/> 
        <ColumnDefinition Width="Auto"/> 
       </Grid.ColumnDefinitions> 
       <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 
       <TextBlock Grid.Column="1" Margin="0,1"> % Per Annum</TextBlock> 
       </Grid> 
      </Themes:ListBoxChrome> 
      <ControlTemplate.Triggers> 
       <Trigger Property="IsEnabled" Value="false"> 
       <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 
       <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 
       </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> 
    <StackPanel> 
    <TextBox Text="50" Style="{StaticResource PerAnnumTextBoxStyle}" Width="100" HorizontalAlignment="Left"/> 
    </StackPanel> 
</Window> 
0

最簡單的,在我的opionion更好的辦法是把文本框裏面StackPanel

<StackPanel Orientation="Horizontal"> 
    <TextBox Text="{Binding Path=MyTextProperty}"/> 
    <Label Content="55% Per Annum" /> 
</StackPanel>