Подтвердить что ты не робот

Как сделать TextBox с кнопкой внутри WPF?

Я хотел бы сделать TextBox с Button внутри, что-то вроде DatePicker, но не совсем. Или это может быть ComboBox внутри TextBox, поэтому вы можете переключать режим TextBox.

Можете ли вы мне помочь?

4b9b3361

Ответ 1

Если вы хотите что-то вроде combobox или time time picker, вы должны создать новый элемент управления, внутри этого нового элемента управления разместите текстовое поле и кнопку рядом друг с другом внутри фрейма, который будет выглядеть как рамка текстового поля - затем переустановить текстовое поле, так что у него нет кадра.

Нажатие кнопки внутри расширенного редактирования отлично, если вы хотите поместить кнопку внутри "документа", но не являетесь хорошей заменой для combobox.

См. шаблон управления ComboBox MSDN

Ответ 2

Я создал элемент управления текстовым полем и добавил Кажется, что это работает, но не идеальная ситуация, потому что она воссоздает другое текстовое поле.

<TextBox.Template>
 <ControlTemplate>
        <Grid>
            <Grid.ColumnDefinitions></Grid.ColumnDefinitions>
            <TextBox Grid.Column="0"></TextBox>
            <Button HorizontalAlignment="Right" Width="25" Grid.Column="1">
            </Button>
        </Grid>         
    </ControlTemplate>
</TextBox.Template>

Ответ 3

Вы можете найти эту ссылку: http://msdn.microsoft.com/en-us/library/ms752068(VS.85).aspx.

"ControlTemplate для TextBox должен содержать ровно один элемент, помеченный как элемент хоста содержимого, этот элемент будет использоваться для визуализации содержимого TextBox. Чтобы пометить элемент как хост контента, назначьте ему специальное имя PART_ContentHost. Элемент хоста содержимого должен быть либо ScrollViewer, либо AdornerDecorator. Элемент хоста содержимого может не содержать дочерние элементы.

Ответ 4

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

Ответ 5

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

Ответ 6

Правильный способ сделать это - использовать шаблон управления в текстовом поле. Что-то вроде ниже. Я использовал это внутри класса, который наследуется от текстового поля и называется ButtonBox. Затем я наследую других от таких, как DateBox, DateTimeBox, SqlServerConnectBox и т.д.

    xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"

<TextBox.Template>
    <ControlTemplate TargetType="{x:Type TextBoxBase}">
        <mwt:ListBoxChrome 
            Background="{TemplateBinding Panel.Background}"
            BorderBrush="{TemplateBinding Border.BorderBrush}"
            BorderThickness="{TemplateBinding Border.BorderThickness}"
            RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
            RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
            Name="Bd"
            SnapsToDevicePixels="True">

            <DockPanel>
                <Button DockPanel.Dock="Right" Name="myButton" Padding="3,0" Click="myButton_Click">...</Button>
                <ScrollViewer Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"></ScrollViewer>
            </DockPanel>
        </mwt:ListBoxChrome>
        <ControlTemplate.Triggers>
            <Trigger Property="UIElement.IsEnabled">
                <Setter Property="Panel.Background" TargetName="Bd">
                    <Setter.Value>
                        <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
                    </Setter.Value>
                </Setter>
                <Setter Property="TextElement.Foreground">
                    <Setter.Value>
                        <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                    </Setter.Value>
                </Setter>
                <Trigger.Value>
                    <s:Boolean>False</s:Boolean>
                </Trigger.Value>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</TextBox.Template>

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

<Style TargetType="{x:Type local:ButtonBox}">
    <Setter Property="Border.BorderThickness" Value="1"></Setter>
    <Setter Property="Border.BorderBrush">
        <Setter.Value>
            <LinearGradientBrush StartPoint="0,0" EndPoint="0,20" MappingMode="Absolute">
                <LinearGradientBrush.GradientStops>
                    <GradientStop Color="#FFABADB3" Offset="0.05" />
                    <GradientStop Color="#FFE2E3EA" Offset="0.07" />
                    <GradientStop Color="#FFE3E9EF" Offset="1" />
                </LinearGradientBrush.GradientStops>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="Control.Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:ButtonBox}">
                <mwt:ListBoxChrome 
                    Background="{TemplateBinding Panel.Background}"
                    BorderThickness="{TemplateBinding Border.BorderThickness}"
                    BorderBrush="{TemplateBinding Border.BorderBrush}"
                    RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
                    RenderFocused="{TemplateBinding UIElement.IsKeyboardFocusWithin}"
                    Name="Bd"
                    SnapsToDevicePixels="True">
                    <DockPanel>
                        <Button
                            DockPanel.Dock="Right"
                            Name="PART_Button"
                            Height="0"
                            Style="{x:Null}"
                            Margin="0"
                            Padding="3,0"
                            Content="{TemplateBinding local:ButtonBox.ButtonContent}"
                            IsTabStop="False">                                
                        </Button>
                        <TextBox
                            BorderBrush="{x:Null}"
                            BorderThickness="0"
                            Margin="0"
                            Name="PART_ContentHost"
                            IsReadOnly="{TemplateBinding TextBox.IsReadOnly}"
                            Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=Text}">                                
                        </TextBox>
                        <!-- ScrollViewer Name="PART_ContentHost" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Margin="1"></ScrollViewer -->
                    </DockPanel>
                </mwt:ListBoxChrome>
                <ControlTemplate.Triggers>
                    <Trigger Property="UIElement.IsEnabled">
                        <Setter Property="Panel.Background" TargetName="Bd">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.ControlBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Setter Property="TextElement.Foreground">
                            <Setter.Value>
                                <DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
                            </Setter.Value>
                        </Setter>
                        <Trigger.Value>
                            <s:Boolean>False</s:Boolean>
                        </Trigger.Value>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="IsTabStop" Value="False"></Setter>
</Style>

Ответ 7

Просто используйте Grid.Column так же, как ниже кода

<TextBox x:Name="txtUrl" Grid.Column="1" Margin="2,2,0,2" VerticalAlignment="Center" Padding="2" PreviewKeyDown="txtUrl_PreviewKeyDown" GotFocus="txtUrl_GotFocus" PreviewMouseDown="txtUrl_PreviewMouseDown"> 

</TextBox>
<eo:BareButton x:Name="btnAddFavorite" Grid.Column=" 1"   HorizontalAlignment="Right" Style="{StaticResource WindowButtonStyle }" Margin="2" >
    <eo:BareButton.Template>
        <ControlTemplate TargetType="{x:Type eo:BareButton}">
            <Border x:Name="PART_Border" Width="22" Height="22" Background="Transparent" VerticalAlignment="Center" Margin="2,0,0,0" CornerRadius="2">
                <Path 
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
                                                            Fill="Yellow" 

            Data="M 2,9 L 8,8 10,2 13,8 19,9 15,13 16,19 10,15 5,19 6,13 2,9"
        SnapsToDevicePixels="false"
            Stroke="{Binding Foreground, RelativeSource={RelativeSource AncestorType={x:Type eo:BareButton}, Mode=FindAncestor}}"
            StrokeThickness="1" />
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="PART_Border" Property="BorderBrush" Value="#666"/>
                    <Setter TargetName="PART_Border" Property="BorderThickness" Value="1"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </eo:BareButton.Template>

</eo:BareButton>

Ответ 8

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

<Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <TextBox VerticalAlignment="Stretch"  HorizontalAlignment="Stretch" Grid.Row="0" />

        <Button Content="Copy" Width="40" Height="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10" Grid.Row="0" />

</Grid>