如何从模板重置TextBox的Text属性?仅限于xaml

时间:2014-03-01 14:25:47

标签: c# wpf xaml

我有一个文本框样式,带有按钮以清除文本框的值,
但是当事件点击按钮时,该值消失并在释放按钮鼠标时重新出现。 在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>

并使用如下:

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

// C# SearchViewModel 

internal class SearchViewModel : ViewModelBase
{
 private string _searchLastName; 

 public string SearchLastName
 {
     get { return this._searchLastName; }
     set
     {
         this._searchLastName = value;
         OnPropertyChanged("SearchLastName");
     }
 }
 ......

怎么样,有可能吗? 有人可以帮助我吗?

此致

4 个答案:

答案 0 :(得分:1)

触发器将自动执行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 
                    }" />

视图模型:

internal class SearchViewModel : INotifyPropertyChanged
    {
        public void RaisePropertyChanged(string propertyname)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private string _searchLastName=string.Empty;

        public string SearchLastName
        {
            get { return _searchLastName; }
            set
            {
                _searchLastName = value;
                RaisePropertyChanged("SearchLastName");
            }
        }

    }

答案 1 :(得分:1)

我认为不可能以你想要的方式做到这一点(虽然我可能错了)。

我的理解是,在第一个实例中(按下按钮之前),名为TextBox的{​​{1}}将从searchTextBox中指定的Path获取其值},ParentTemplate属性 - 绑定到本地TextBox.Text属性。

当您按下按钮时,您将覆盖已在SearchLastName控件上设置的绑定,以便不再从绑定searchTextBox获取TextBox.Text的值到Path,只需将其设置为空字符串文字SearchLastName,这就是您显示的内容(从""设置)。

释放按钮后,绑定将恢复到您之前从未更改过的ParentTemplateTrigger属性,并保持不变。

如果你想要实际清除Path属性,你必须让按钮触发一个命令/动作来清除你的搜索,或者操纵控件的SearchLastName属性(我相信有很多方法可以在UI中完成相对绑定,但对于一个简单的问题,它可能是一个棘手的解决方案)。我不相信你能用切换模板来做到这一点。

答案 2 :(得分:0)

第一个问题是您在模板内的TextBox上缺少UpdateSourceTrigger = PropertyChanged。 TextBox的默认值为LostFocus。如果您希望在键入textBox时更新source属性,则需要将其设置为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}" />

第二次,您在Trigger按钮值上使用了IsPressed。因此,一旦IsPressed值反转,它将恢复。 IsPressed状态是暂时的,您需要更新Click事件的绑定属性,您可以通过EventTrigger更新该事件,但遗憾的是它无法在内部设置。

因此,您应该通过将Text绑定到ViewModel中的ICommand来更改{{1}},并简单地从命令方法设置基础绑定属性。

答案 3 :(得分:0)

最后,您的评论我这样做了:

在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>

我已删除了触发器

工作正常,但我想要纯xaml。

非常感谢所有人:)

祝你好运