Wie einen Text mit einem Knopf im Innern in WPF machen?
Frage
Ich möchte eine TextBox
mit einem Button
machen innen, so etwas wie ein DatePicker
, aber nicht genau. Oder es kann ein ComboBox
innerhalb des TextBox
sein, so können Sie den Modus des TextBox
wechseln.
Können Sie mir helfen?
Lösung
Wenn Sie so etwas wie eine Combobox oder ein Datum Zeitauswahl Sie ein neues Steuerelement erstellen sollten, in diesem neuen Steuerplatz ein Textfeld und eine Schaltfläche nebeneinander in einem Rahmen, der wie der Rahmen eines Textbox aussieht - dann restyle die Textbox, damit es nicht einen Rahmen hat.
eine Schaltfläche in einem Rich-Edit-Putten ist groß, wenn Sie auf eine Schaltfläche in einem „Dokument“ setzen wollen, aber keine guten Ersatz für eine Combobox.
Sehen Sie die ComboBox-Steuerelementvorlage MSDN
Andere Tipps
Sie können diesen Link finden hilft: http: // msdn.microsoft.com/en-us/library/ms752068(VS.85).aspx .
"Die Control für ein TextBox muss genau ein Element enthalten, das als Inhaltshost Element markiert ist, dieses Element wird verwendet, um den Inhalt der TextBox zu machen, um ein Element als Inhalt Host zu markieren, weisen Sie den speziellen Namen. PART_ContentHost. Der Elementgehalt Host muss entweder ein Scroll oder AdornerDecorator. Der Inhalt Host-Element keine untergeordnete Elemente hosten kann. "
Ich habe eine Textbox-Steuerelement und hat dieses Bild Es scheint zu funktionieren, aber nicht die ideale Situation cos es erschafft eine weitere Textbox.
<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>
Sie können RichTextBox statt Textbox verwenden und sie unterstützen Flowdocument, in dem Sie auf die Schaltfläche in es platzieren können.
Sie können auch ein Label verwenden und seine Vorlage ändern, um einen Knopf darin aufzunehmen. Um einen guten Überblick über Unterschiede zwischen Label und Textblock finden Sie unter diesen Beitrag .
Die richtige Methode, dies zu tun, ist eine Steuer Vorlage auf der Textbox zu verwenden. So etwas wie unten. Früher habe ich dies in einer Klasse, die von Textbox erbt und nannte es ButtonBox. Ich erben dann andere von dieser wie DateBox, DateTimeBox, SqlServerConnectBox etc.
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>
Edit: Ich habe die Methode ändern, die ich verwendet wurde, so dass es von der Kontrolle und nicht der Textbox erbt. Das funktioniert gut, weil die Steuerung besteht nur aus einem Rahmen, ein Textfeld und eine Schaltfläche. Ich war Fokus Probleme mit der obigen Lösung zu bekommen. Dies wird neue Vorlage, ich habe meine Steuer ein ButtonBox
genannt<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>
Just Grid.Column verwenden gleiche wie unter Code
<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>
Sie können ein Gitter verwenden diese Aufgabe zu erfüllen. Hier finden Sie, wie ich eine Schaltfläche erstellt, die an der rechten unteren Ecke eines TextBox erscheint:
<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>