How to create a text box and a label with an oblique border?

I am trying to create a text box in Wpf that has a shortcut in the upper left corner, and additionally this label should have a border with a slope on one side.

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

Now for one or two specific cases that are doable with a workaround, when I just used the lines for the border. Now that I want to use it a little more, I need to do it correctly, especially in the sense that it is scalable.

I would be very happy if someone could point me in the right direction.

Edit: Thus, the code that I use after accounting for the answers so far that I created as a user control is:

<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> 

This works, and the only thing that bothers me is the variability of the label border, which is very unpleasant to do, but, fortunately, it is not necessary in my case.

+6
source share
3 answers

This is another solution that uses Style instead of UserControl .

I assume that Label is a TextBox description, inside the style I created a TextBlock (replacing Label , since in this case it will be superfluous), of which Text associated with the Tag parent TextBox . Then it will display everything that you put in your Tag .

I also grouped TextBlock and two Paths in a Grid , determined that its columns will be automatically set, so you will no longer have a problem with resizing.

The screenshot below is two TextBoxes with different labels. enter image description here

TextBox Style

 <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> 

Text boxes

  <TextBox Tag="Label" Text="This is a textbox" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center" FontSize="24" Style="{DynamicResource MyTextBoxStyle}"/> <TextBox Tag="Long Label" Text="This is a textbox" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Bottom" FontSize="24" Style="{DynamicResource MyTextBoxStyle}"/> 

Hope this helps. :)

+4
source

You can create a Path and use it as a border and place the border less than a textbox in relation to it. Please see my answer in a similar question.

+2
source

In this case, I would build a UserControl that contains the controls you need (two labels and a slope). Here is an article on how to create UserControls and reference them in your application: http://www.codeproject.com/KB/WPF/UserControl.aspx

If you have Expression Blend, you can easily draw a Slope, otherwise you will have to manually code the WPF Geometry syntax: http://msdn.microsoft.com/en-us/library/ms752293.aspx

Here is an example of a slope path that should give rise to:

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

Source: https://habr.com/ru/post/903091/


All Articles