如何创建带有倾斜边框的文本框和标签?

时间:2011-12-05 10:35:23

标签: c# wpf mvvm expression-blend

我正在尝试在Wpf中创建一个文本框,其左上角有一个标签,并且这个标签应该有一个边上有一个斜坡的边框。

http://imgur.com/Nupbf The way I tried it

现在针对一个或两个特定情况可以使用解决方法,我只使用了边界线。现在我想要更多地使用它,我需要以正确的方式进行,特别是在可扩展的方式。

如果有人能指出我正确的方向,我会很高兴。

编辑: 所以我考虑到目前为止的响应后使用的代码,我创建的代码是用户控件:

<Grid Height="93" Width="335">
<TextBox TextWrapping="Wrap" Text="{Binding TextboxText}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" BorderBrush="{x:Null}" Background="{x:Null}"/>
<Path Data="M384,242 L442.5,242" HorizontalAlignment="Left" Height="1" Margin="0,28.667,0,0" Stretch="Fill" VerticalAlignment="Top" Width="59.5">
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#8EFFFFFF"/>
<GradientStop Color="White" Offset="0.991"/>
</LinearGradientBrush>
</Path.Fill>
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<LinearGradientBrush.RelativeTransform>
<TransformGroup>                                        <ScaleTransform CenterY="0.5" CenterX="0.5"/>                                   <SkewTransform CenterY="0.5" CenterX="0.5"/>                                <RotateTransform Angle="90" CenterY="0.5" CenterX="0.5"/>                       <TranslateTransform/>
</TransformGroup>
</LinearGradientBrush.RelativeTransform>
<GradientStop Color="White" Offset="0.009"/>
<GradientStop Color="#5FFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Path.Stroke>
</Path>
<Label Content="{Binding LabelText}" HorizontalAlignment="Left" Width="113" FontSize="16" Height="40" VerticalAlignment="Top" BorderBrush="White" Margin="0,0.167,0,0"/>
<Path Data="M125.12574,28.672087 L145.37561,-1.1668457" HorizontalAlignment="Left" Height="30.839" Margin="58.125,-1,0,0" Stretch="Fill" VerticalAlignment="Top" Width="21.25">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#51FFFFFF" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Path.Stroke>
<Path.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#49FFFFFF" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Path.Fill>
</Path>
<Path Data="M0,83 L181.35815,83" Fill="#FFF4F4F5" Height="1" Stretch="Fill" VerticalAlignment="Bottom" Width="327" StrokeThickness="2" Margin="0,0,10,10">
<Path.Stroke>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</Path.Stroke>
</Path>
</Grid>

它有效,唯一令我困扰的是标签边框的可恢复性,这很烦人但幸运的是在我的情况下没有必要。

3 个答案:

答案 0 :(得分:4)

这是另一种使用Style而不是UserControl的解决方案。

我认为LabelTextBox的描述,在风格中,我创建了一个TextBlock(替换了Label,因为它会在此过度杀伤case)其中Text绑定到父Tag的{​​{1}}。然后它会显示您放在TextBox中的任何内容。

此外,我已将Tag和两个TextBlock分组到Paths,将其列设置为自动调整大小,以便您不再遇到可重新调整问题。

下面的屏幕截图是两个Grid,带有不同的标签。 enter image description here

TextBox样式

TextBoxes

TextBoxes

<Style x:Key="MyTextBoxStyle" TargetType="{x:Type TextBox}">
    <Setter Property="Background" Value="Black" />
    <Setter Property="Foreground" Value="#FFB8B8B8" />
    <Setter Property="BorderBrush" Value="#FF484848" />
    <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" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border x:Name="BottomLine" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,0,0,1">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="Auto" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid x:Name="TopPanel" HorizontalAlignment="Left">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <TextBlock d:LayoutOverrides="Width, Height" x:Name="Caption" TextWrapping="Wrap" Text="{TemplateBinding Tag}" FontSize="14.667" VerticalAlignment="Center" Margin="4,0,24,0" />
                            <Path x:Name="BottomPath" Data="M384,242 L442.5,242" Stretch="Fill" VerticalAlignment="Bottom" Margin="0,0,-1.3,0">
                                <Path.Stroke>
                                    <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                                        <LinearGradientBrush.RelativeTransform>
                                            <TransformGroup>
                                                <ScaleTransform CenterY="0.5" CenterX="0.5" />
                                                <SkewTransform CenterY="0.5" CenterX="0.5" />
                                                <RotateTransform Angle="90" CenterY="0.5" CenterX="0.5" />
                                                <TranslateTransform />
                                            </TransformGroup>
                                        </LinearGradientBrush.RelativeTransform>
                                        <GradientStop Color="White" Offset="0.009" />
                                        <GradientStop Color="#5FFFFFFF" Offset="1" />
                                    </LinearGradientBrush>
                                </Path.Stroke>
                            </Path>
                            <Path x:Name="RightPath" Data="M125.12574,28.672087 L145.37561,-1.1668457" Stretch="Fill" Grid.Column="1">
                                <Path.Stroke>
                                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                        <GradientStop Color="#51FFFFFF" Offset="0" />
                                        <GradientStop Color="White" Offset="1" />
                                    </LinearGradientBrush>
                                </Path.Stroke>
                            </Path>
                        </Grid>
                        <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" RenderMouseOver="{TemplateBinding IsMouseOver}" RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true" Margin="0,0,0,-0.001" d:LayoutOverrides="Width, Height" Grid.Row="1">
                            <ScrollViewer x:Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Microsoft_Windows_Themes:ListBoxChrome>
                    </Grid>
                </Border>
                <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>

希望这会有所帮助。 :)

答案 1 :(得分:2)

您可以创建Path并将其用作边框,并将相对于它的边框设置为textbox。 请see my answer提出类似的问题。

答案 2 :(得分:0)

在这种情况下,我构建一个UserControl,其中包含您想要的控件(两个标签和斜率)。 这是一篇关于如何创建UserControl并在您的应用程序中引用它们的文章: http://www.codeproject.com/KB/WPF/UserControl.aspx

如果你有Expression Blend,你可以很容易地绘制一个Slope,否则你必须使用WPF的Geometry语法手动编码: http://msdn.microsoft.com/en-us/library/ms752293.aspx

这是一个斜坡路径的示例,应该给出一个开始:

<Path Data="M0.5,40 L176,40 M177,40 L217,0.5" Fill="#FFF4F4F5" />