如何通过单击此模板内的按钮来为父控件模板属性设置某些值?

问题描述 投票:0回答:1

我想实现一些带有循环图标和占位符的自定义搜索文本框。因此,我创建了一个自定义控件模板,其中有用于循环图标的 TextBlock(我使用了特定字体中的一些符号)、ScrollViewer(它是显示文本的默认 TextBox 模板中的默认控件)、带有一些文本“搜索”的 TextBlock占位符(当我的文本框聚焦或用户写入内容时不可见)和按钮(当文本框为空时不可见,当用户写入内容时可见,应在单击时清除文本框的文本)。这是它的样子:

enter image description here

这是该控制模板的代码:

<ControlTemplate x:Key="SearchTextBoxTemplate" TargetType="{x:Type TextBox}">
    <Border Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            CornerRadius="5"
            SnapsToDevicePixels="True">
        <Grid HorizontalAlignment="Stretch"
              VerticalAlignment="Stretch">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBlock Margin="6,1,6,0"
                       Grid.Column="0"
                       FontFamily="{Binding Font, Source={StaticResource Icons}}"
                       FontSize="{TemplateBinding FontSize}"
                       Foreground="#8C8C8C"
                       FontWeight="Normal"
                       Text="&#xE71E;"
                       HorizontalAlignment="Left"
                       VerticalAlignment="Center"/>
            <TextBlock x:Name="Placeholder"
                       Grid.Column="1"
                       FontSize="{TemplateBinding FontSize}"
                       Focusable="False"
                       Text="Search"
                       Foreground="#AAAFB4"
                       IsHitTestVisible="False"
                       HorizontalAlignment="Left"
                       VerticalAlignment="Center"
                       Visibility="Collapsed"/>
            <ScrollViewer x:Name="PART_ContentHost"
                          Grid.Column="1"
                          Focusable="False"
                          HorizontalScrollBarVisibility="Hidden"
                          VerticalScrollBarVisibility="Hidden"
                          VerticalContentAlignment="Center"
                          VerticalAlignment="Center"/>
            <Button x:Name="ClearSearchText"
                    Margin="5,0,6,0"
                    Grid.Column="2"
                    Background="Transparent"
                    BorderBrush="Transparent"
                    BorderThickness="0"
                    Cursor="Hand"
                    FontFamily="{Binding Font, Source={StaticResource ResourceKey=Icons}}"
                    HorizontalAlignment="Right"
                    VerticalAlignment="Center">
                <Button.Content>
                    <Grid>
                        <TextBlock FontSize="12"
                                   Foreground="#D1D1D1"
                                   Text="&#xE91F;"/>
                        <TextBlock FontSize="8"
                                   HorizontalAlignment="Center"
                                   VerticalAlignment="Center"
                                   Foreground="White"
                                   Text="&#xE711;"/>
                    </Grid>
                </Button.Content>
            </Button>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Opacity" Value="0.6"/>
        </Trigger>
        <Trigger Property="Text" Value="{x:Static sys:String.Empty}">
            <Setter TargetName="ClearSearchText" Property="Visibility" Value="Collapsed"/>
        </Trigger>
        <Trigger Property="Text" Value="{x:Null}">
            <Setter TargetName="ClearSearchText" Property="Visibility" Value="Collapsed"/>
        </Trigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsKeyboardFocusWithin" Value="False"/>
                <Condition Property="Text" Value="{x:Static sys:String.Empty}"/>
            </MultiTrigger.Conditions>
            <Setter TargetName="Placeholder" Property="Visibility" Value="Visible"/>
        </MultiTrigger>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsKeyboardFocusWithin" Value="False"/>
                <Condition Property="Text" Value="{x:Null}"/>
            </MultiTrigger.Conditions>
            <Setter TargetName="Placeholder" Property="Visibility" Value="Visible"/>
        </MultiTrigger>
        <Trigger SourceName="ClearSearchText" Property="IsPressed" Value="True">
            <Setter Property="Text" Value="{x:Null}"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

一切正常。但是,我仍然无法编写正确的逻辑,通过单击按钮来清除 TextBox 的文本。我想在 XAML 模板中执行此操作,而不添加一些新的后端代码或创建自定义用户控件。

正如您在 ControlTemplate.Triggers 组末尾所看到的,我尝试添加一个触发器,以在按下按钮时清除文本。但它不起作用:

<Trigger SourceName="ClearSearchText" Property="IsPressed" Value="True">
    <Setter Property="Text" Value="{x:Null}"/>
</Trigger>

此外,我尝试将相同 Button 属性的检查添加到 Button 样式:

<Button>
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <Trigger Property="IsPressed" Value="True">
                    .... Some setter
                </Trigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

但是我不知道如何从放置此按钮的父控件模板中正确获取 Text 属性。

那么如何正确执行此操作以及如何通过单击按钮清除文本?

wpf button triggers setter controltemplate
1个回答
0
投票

使用Microsoft.Xaml.Behaviors.Wpf的EventTrigger和ChangePropertyAction,您可以在触发Button.Click事件时设置TextBox.Text属性。

<Button x:Name="ClearSearchText"
        ...>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:ChangePropertyAction TargetObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"
                                    PropertyName="Text" Value="{x:Null}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

顺便说一下,如果目标是 TextBlock.Text 属性,您还可以使用普通的 EventTrigger 和 StringAnimationUsingKeyFrames。但它不适用于 TextBox.Text 属性,因为它不可设置动画。

© www.soinside.com 2019 - 2024. All rights reserved.