TextBox с маленьким треугольником в углу - PullRequest
2 голосов
/ 29 января 2020

Я пытаюсь создать TextBox с маленьким треугольником в верхнем правом углу. Я действительно не знаю, как этого добиться. Я попытался добавить полигон в текстовое поле следующим образом:

<TextBox 
      x:Name="PartnerEmail"
      TextWrapping="Wrap" 
      MaxLength="50"
      Grid.Column="1"
      Grid.Row="12"
      Margin="5,1,0,1" >
      <TextBox.Style>
          <Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
                <Setter Property="Template">
                      <Setter.Value>
                           <ControlTemplate>
                                <Polygon Points="0,0 10,0 0,10 0,0" Margin="0,2,2,0" HorizontalAlignment="Right" Fill="#fcba03" FlowDirection="RightToLeft"/>
                           </ControlTemplate>
                      </Setter.Value>
                </Setter>
           </Style>
      </TextBox.Style>

Но, очевидно, это не сработает, потому что я переопределяю шаблон по умолчанию, поэтому после этого все, что у меня есть, это полигон и текстовое поле исчезнет. У кого-нибудь может быть хорошее решение для этого?

Ответы [ 3 ]

1 голос
/ 30 января 2020

Вы на правильном пути, но работаете слишком усердно ...

Следует помнить об элементах пользовательского интерфейса в WPF - они работают в слоях. Думайте об элементах как о совокупности более мелких предметов, которые вы хотите разместить в трехмерном пространстве. Вы больше не просто работаете в двумерном пространстве рисования, как в пространстве визуализации GDI WinForms.

Итак, давайте логически подумаем о том, что вы хотите сделать здесь. Давайте попробуем достичь нескольких целей в нашем решении:

  • Позволяет создать шаблон элемента управления, который позволит нам повторно использовать наш недавно отчеканенный элемент управления.
  • Позволяет сделать элемент управления полностью переносимым в трехмерном пространстве, т. е. не использовать растровые изображения, которые будут искажаться, если мы изменим размеры нашего элемента управления - давайте придерживаться геометрии только для рисования.

  • Позволяет легко решить, насколько велика треугольник в углу.

  • Давайте решим, что потом можно будет легко вносить изменения, такие как размещение треугольника (вы хотите изменить его местоположение), тестирование попадания (если оно является частью поверхности текста). или граница?), цвет (опять же, граница или текст?) и т. д. c.

Хорошо, чтобы решить эту проблему, я ссылался на идею объектов в слоях. Давайте разделим нашу поверхность рисования на сетку:

enter image description here

Это означает, что мы хотим использовать элемент управления Grid. Мы хотим определить две строки и два столбца, и мы хотим, чтобы TextBox охватывал все 4 ячейки. Мы обязательно установим Rowspan и Columnspan для заполнения сетки.

Затем мы добавим второй элемент, наш Polyline треугольник в строку 1 столбца 1, и добавим его после текстовое поле. Таким образом, Z-порядок будет сверху.

Вот тогда шаблон управления:

<Window.Resources>
    <Style x:Key="TriangleTextBox" TargetType="{x:Type TextBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBox}">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="10"/>
                            <RowDefinition Height="6*"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="6*" />
                            <ColumnDefinition Width="10" />
                        </Grid.ColumnDefinitions>
                        <TextBox Grid.Row="0" Grid.Column="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Margin="0,0,0,0" Text="{TemplateBinding Text}" BorderThickness="1"/>
                        <Polygon Grid.Row="0" Grid.Column="1" Points="0,0 10,0 0,10 0,0" Fill="Black" FlowDirection="RightToLeft"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

Обратите внимание, что мы установили ключ в "TriangleTextBox".

Теперь просто использовать наш шаблон управления следующим образом:

<Grid>
    <TextBox Style="{StaticResource ResourceKey=TriangleTextBox}" Width="100" Height="20"/>
</Grid>

И вот он у вас:

enter image description here

Вы можете расширить это оттуда.

0 голосов
/ 29 января 2020

Создайте пользовательский (составной) элемент управления, который будет иметь многоугольник (нарисованный последним) для наложения текстового поля в углу по мере необходимости. Использование Canvas элемента управления для конкретного c размещения или в пределах Grid для общего размещения в элементе управления.


Здесь я должен был поместить значок поиска поверх текстового поля в сетке. Я устанавливаю ZIndex по мере необходимости.

enter image description here

Код

<TextBox Grid.ColumnSpan="2" 
         Panel.ZIndex="0" 
         HorizontalAlignment="Stretch" 
         VerticalAlignment="Stretch"  />

<Image Grid.Column="1" Source="../Assets/Search.png" 
       Panel.ZIndex="1"
       HorizontalAlignment="Stretch" 
       VerticalAlignment="Stretch"  
       Stretch="Uniform"/>
0 голосов
/ 29 января 2020

Вы по сути заменяете все текстовое поле ничем иным, как треугольником. Вы должны скопировать базовый шаблон и изменить его оттуда:

    <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}">
                    <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"/>-->
                        <Grid>
                            <Polygon Points="0,0 10,0 0,10 0,0" Margin="0,2,2,0" HorizontalAlignment="Right" Fill="#fcba03" FlowDirection="RightToLeft"/>
                            <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
                        </Grid>
                    </Border>
                    <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}"/>
                        </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>

Что касается самого шаблона, вы получите его от microsoft или через visual studio .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...