C# 如何从模板中重置TextBox的属性文本?仅在xaml中

C# 如何从模板中重置TextBox的属性文本?仅在xaml中,c#,wpf,xaml,C#,Wpf,Xaml,我有一个文本框样式,带有清除文本框值的按钮, 但当事件单击按钮时,该值将消失,并在释放鼠标按钮时重新出现。 下面是xaml代码: <ResourceDictionary ..... <Style x:Key="SearchBoxTemplate" TargetType="{x:Type TextBox}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate Tar

我有一个文本框样式,带有清除文本框值的按钮,
但当事件单击按钮时,该值将消失,并在释放鼠标按钮时重新出现。 下面是xaml代码:

<ResourceDictionary .....

<Style x:Key="SearchBoxTemplate" TargetType="{x:Type TextBox}">
 <Setter Property="Template">
  <Setter.Value>
   <ControlTemplate TargetType="{x:Type TextBox}">
    <Border BorderBrush="LightGray" BorderThickness="1">
     <StackPanel Orientation="Horizontal" >
      <Grid Width="{TemplateBinding Width}">
       <Grid.ColumnDefinitions>
           <ColumnDefinition Width="8.6*" />
           <ColumnDefinition Width="1.4*" />
       </Grid.ColumnDefinitions>
       <TextBox Background="Transparent" x:Name="searchTextBox" Grid.Column="0"
                HorizontalAlignment="Stretch" BorderThickness="0"
               Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Text, Mode=TwoWay}"
                Height="{TemplateBinding Height}" />
       <Button Background="Transparent" 
               x:Name="clearButton"  Content="X"
               Margin="2" Width="Auto" Height="Auto"
               Grid.Column="1"/>
      </Grid>
     </StackPanel>
    </Border>
    <ControlTemplate.Triggers>
     <Trigger SourceName="clearButton"  Property="IsPressed"  Value="True" >
         <Setter TargetName="searchTextBox" Property="TextBox.Text" Value="" />
     </Trigger>
    </ControlTemplate.Triggers>
   </ControlTemplate>
  </Setter.Value>
 </Setter>
</Style>

触发器将自动执行IsPressed=“False”的操作。编写侦听IsPressed=“False”的触发器

最新答复:

<Style x:Key="SearchBoxTemplate" TargetType="{x:Type TextBox}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TextBox}">
                            <Border BorderBrush="LightGray" BorderThickness="1">
                                <StackPanel Orientation="Horizontal" >
                                    <Grid Width="{TemplateBinding Width}">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="8.6*" />
                                            <ColumnDefinition Width="1.4*" />
                                        </Grid.ColumnDefinitions>
                                        <TextBox Background="Transparent" x:Name="searchTextBox" Grid.Column="0"
                HorizontalAlignment="Stretch" BorderThickness="0"

                Height="{TemplateBinding Height}" />
                                        <Button Background="Transparent" 
               x:Name="clearButton"  Content="X"
               Margin="2" Width="Auto" Height="Auto"
               Grid.Column="1"/>
                                    </Grid>
                                </StackPanel>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger SourceName="clearButton"  Property="IsPressed"  Value="True" >
                                    <Setter TargetName="searchTextBox" Property="Text" Value="" />
                                </Trigger>

                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

<TextBox  Style="{StaticResource SearchBoxTemplate}"
             Width="200"
             Text="{Binding SearchLastName,Mode=TwoWay,
                    UpdateSourceTrigger=PropertyChanged 
                    }" />

我不认为有可能以你想要的方式来做这件事(尽管我可能是错的)

我的理解是,首先(在按下按钮之前),名为
searchTextBox
TextBox
将从
ParentTemplate
中指定的
路径获取其值,
TextBox.Text
属性-绑定到本地
SearchLastName
属性

当您按下按钮时,您将覆盖已在
searchTextBox
控件上设置的绑定,以便
TextBox.Text的值不再从绑定的
路径
SearchLastName
,而是简单地设置为空字符串literal
,这就是您看到的显示内容(从您的
ParentTemplateTrigger
设置)

松开按钮后,绑定将恢复到您的属性的上一个
路径
,该路径从未更改,并将保持不变


如果要实际清除
SearchLastName
属性,则必须使按钮触发一个命令/操作以清除搜索,或者操纵控件的
Text
属性(我相信有一些方法可以完全在具有相对绑定的UI中实现,但对于一个简单的问题来说,这可能是一个棘手的解决方案)。我不相信您可以通过切换模板来实现这一点。

首先,问题是您在模板内的文本框上缺少
UpdateSourceTrigger=PropertyChanged
。文本框的默认值是
LostFocus
。如果您希望更新源属性,则需要将其设置为
PropertyChanged
在文本框中键入内容时被忽略

<TextBox Background="Transparent" x:Name="searchTextBox" Grid.Column="0"
         HorizontalAlignment="Stretch" BorderThickness="0"
         Text="{Binding RelativeSource={RelativeSource TemplatedParent},
                   Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
         Height="{TemplateBinding Height}" />

Second,您已经在按钮的
IsPressed
值上使用了
Trigger
。因此,一旦
IsPressed
值被反转,它就会还原。
IsPressed
状态是瞬态的,您需要更新
单击
事件的绑定属性,您可以通过
EventTrigger
实现该属性,但遗憾的是它是c里面没有塞特


因此,您应该通过将
文本绑定到ViewModel中的
ICommand
来更改
文本,只需从command方法设置基础绑定属性即可。

最后,根据您的注释,我做了以下操作:

在SearchviewModel中

    .....
    private ICommand clearCommand;
    public ICommand ClearCommand
    {
        get
        {
            if (this.clearCommand == null)
                this.clearCommand = new RelayCommand(() => this.ClearSearch(), ()=> CanSearch());

            return this.clearCommand;
        }
    }

    void ClearSearch()
    {
        Search = string.Empty;
    }

    bool CanSearch()
    {
        return !string.IsNullOrEmpty(_search);
    }
    .....
时髦

 <Style....
  <Button
    ....
    Command="{Binding ClearCommand}" />
 </Style>

您的目标是清除绑定属性,还是只是试图更改控件上显示的文本?两者都是,我认为如果其中一个被删除,另一个也会被删除!!!这不是真的?我已经尝试了IsPressed false和true,但都不起作用。当我在文本框中键入时,viewModel中的属性不会更改,并且不会触发event on property changed。您解决方案很好地清除文本,但在SearchViewModel not update event fire中:(当我键入文本时,SearchLastName不会更新。当我单击“清除”按钮时,SearchLastName也不会更新。您可以使用“删除”按钮覆盖文本框样式。默认样式在此链接中是这似乎是发生的情况:(但是你仍然需要添加
UpdateSourceTrigger=PropertyChanged
,以防你想在输入textBox而不是lostFocus后立即更新源属性。我做到了,你可以在我上面的第一篇文章中看到:)我指的是模板内的textBox,即
searchTextBox
,而不是外部的。。
    .....
    private ICommand clearCommand;
    public ICommand ClearCommand
    {
        get
        {
            if (this.clearCommand == null)
                this.clearCommand = new RelayCommand(() => this.ClearSearch(), ()=> CanSearch());

            return this.clearCommand;
        }
    }

    void ClearSearch()
    {
        Search = string.Empty;
    }

    bool CanSearch()
    {
        return !string.IsNullOrEmpty(_search);
    }
    .....
 <Style....
  <Button
    ....
    Command="{Binding ClearCommand}" />
 </Style>