web-dev-qa-db-ja.com

WPFでボタン付きのTextBoxを作成するにはどうすればよいですか?

TextBoxのようなButtonを内部に持つDatePickerを作成したいのですが、正確ではありません。または、ComboBox内のTextBoxにすることもできるので、TextBoxのモードを切り替えることができます。

手伝って頂けますか?

15
Max Galkin

コンボボックスや日時ピッカーのようなものが必要な場合は、新しいコントロールを作成する必要があります。この新しいコントロール内に、テキストボックスのフレームのように見えるフレーム内にテキストボックスとボタンを並べて配置します。次に、テキストボックスのスタイルを変更します。フレームがありません。

リッチエディット内にボタンを配置することは、「ドキュメント」内にボタンを配置したいが、コンボボックスの代わりにはなりたくない場合に最適です。

ComboBoxコントロールテンプレートを参照してください [〜#〜] msdn [〜#〜]

12
Nir

このリンクが役立つ場合があります: http://msdn.Microsoft.com/en-us/library/ms752068(VS.85).aspx

「TextBoxのControlTemplateには、コンテンツHost要素としてタグ付けされた要素が1つだけ含まれている必要があります。この要素は、TextBoxのコンテンツをレンダリングするために使用されます。要素をコンテンツホストとしてタグ付けするには、特別な名前PART_ContentHostを割り当てます。 content Host要素は、ScrollViewerまたはAdornerDecoratorのいずれかである必要があります。contentHost要素は、子要素をホストすることはできません。」

5
Xiaoqing

テキストボックスコントロールを作成して追加しました。これは機能しているようですが、別のテキストボックスを再作成するので理想的な状況ではありません。

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

以下のコードと同じように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>
0
Narendra

これを行う正しい方法は、テキストボックスでコントロールテンプレートを使用することです。以下のようなもの。これをtextboxから継承するクラス内で使用し、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>
0
MikeKulls

ラベルを使用してテンプレートを変更し、ボタンを含めることもできます。 LabelとTextBlockの違いの概要については、 この投稿 を参照してください。

0
japf

テキストボックスの代わりにRichTextBoxを使用でき、ボタンを配置できるフロードキュメントをサポートします。

0
Firoz