【问题标题】:Include a Button in a TextBox在文本框中包含一个按钮
【发布时间】:2011-05-26 08:00:03
【问题描述】:

我想添加一个小按钮,它会删除TextBox中的所有文本。是否可以将此“删除”按钮放入文本框(如 iPhone 文本框)?

我希望在你的帮助下它看起来像这样:

我用 controltemplate 玩了一些东西,但没有得到想要的结果。

解决此问题的一种方法是使用按钮的负边距,但我认为这不是一个干净的解决方案。

谢谢!

【问题讨论】:

    标签: wpf xaml wpf-controls controltemplate


    【解决方案1】:

    使用交互性获得了一些东西,但你可能不需要:

    <LinearGradientBrush x:Key="TextBoxBorder" EndPoint="0,20" MappingMode="Absolute" StartPoint="0,0">
        <GradientStop Color="#ABADB3" Offset="0.05" />
        <GradientStop Color="#E2E3EA" Offset="0.07" />
        <GradientStop Color="#E3E9EF" Offset="1" />
    </LinearGradientBrush>
    <Style x:Key="ExtendedTextBoxTemplate" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}" />
        <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorder}" />
        <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}">
                    <!-- Here i just wrap the content in a grid and place a button on the right, needs to be styled though -->
                    <Grid>
                        <Microsoft_Windows_Themes:ListBoxChrome x:Name="Bd"
                                BorderBrush="{TemplateBinding BorderBrush}"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                RenderMouseOver="{TemplateBinding IsMouseOver}"
                                RenderFocused="{TemplateBinding IsKeyboardFocusWithin}" SnapsToDevicePixels="true">
                            <ScrollViewer x:Name="PART_ContentHost"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </Microsoft_Windows_Themes:ListBoxChrome>
                        <Button Content="X" HorizontalAlignment="Right">
                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="Click">
                                    <ta:ClearTextAction
                                            Target="{Binding RelativeSource={RelativeSource TemplatedParent}}" />
                                </i:EventTrigger>
                            </i:Interaction.Triggers>
                        </Button>
                    </Grid>
                    <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>
    
    class ClearTextAction : TriggerAction<Button>
    {
        public static readonly DependencyProperty TargetProperty =
                DependencyProperty.Register("Target", typeof(TextBox), typeof(ClearTextAction), new UIPropertyMetadata(null));
        public TextBox Target
        {
            get { return (TextBox)GetValue(TargetProperty); }
            set { SetValue(TargetProperty, value); }
        }
    
        protected override void Invoke(object parameter)
        {
            Target.Clear();
        }
    }
    

    您可以通过添加此样式使按钮仅在 TextBox-MouseOver 上显示:

    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Setter Property="Visibility" Value="Hidden" />
            <Style.Triggers>
                <DataTrigger
                        Binding="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsMouseOver}"
                        Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
    

    【讨论】:

      【解决方案2】:

      假设您不希望文本或光标消失在按钮后面,唯一干净的方法是重新模板 TextBox。如果您对此并不大惊小怪,那么您可以这样做:

      <Grid>
          <TextBox/>
          <Image ... VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0 0 3 0"/>
      </Grid>
      

      【讨论】:

      • 如果您决定重新模板化 TextBox 控件,我建议使用 Expression Blend 提取默认控件模板,编辑现有的模板比从头开始更容易!
      【解决方案3】:

      您可以轻松地从文本框派生并使用您想要的功能创建自己的文本框。这就是 wpf 提供的灵活性。请参阅下面的链接

      http://davidowens.wordpress.com/2009/02/18/wpf-search-text-box/

      【讨论】:

      • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
      猜你喜欢
      • 1970-01-01
      • 2013-02-07
      • 2014-09-29
      • 1970-01-01
      • 2013-08-08
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多