通过XAML在WPF中的TextBox的TextChanged事件上启用/禁用Button

时间:2014-01-31 00:45:31

标签: c# wpf xaml button

WPF中有TextBox和Button控件:

<TextBox Name="BackUpTextBox" />
<Button  Name="BackUpSave" Content="Save" />

如果更改了BackUpTextBox的文本,则必须启用Button BackUpSave。 我知道如何通过C#代码通过BackUpTextBox TextChanged事件来做到这一点。 但有没有办法通过XAML表示法启用/禁用按钮?

2 个答案:

答案 0 :(得分:3)

您可以通过EventTrigger实现这一目标。在StackPanel中包含两个控件,以便将TextChanged 事件路由到其父StackPanel

在这种情况下,通过将IsEnabled设置为True来启用按钮。

<StackPanel>
   <TextBox x:Name="BackUpTextBox"/>
   <Button x:Name="BackUpSave" Content="Save" IsEnabled="False"/>
   <StackPanel.Triggers>
      <EventTrigger RoutedEvent="TextBox.TextChanged">
         <BeginStoryboard>
           <Storyboard>
            <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled"
                                            Storyboard.TargetName="BackUpSave">
                <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="True"/>
            </BooleanAnimationUsingKeyFrames>
           </Storyboard>
        </BeginStoryboard>
     </EventTrigger>
     <EventTrigger RoutedEvent="Button.Click">
       <BeginStoryboard>
         <Storyboard>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled"
                                          Storyboard.TargetName="BackUpSave">
                 <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False"/>
          </BooleanAnimationUsingKeyFrames>
         </Storyboard>
       </BeginStoryboard>
     </EventTrigger>
     <EventTrigger RoutedEvent="Loaded">
       <BeginStoryboard>
         <Storyboard>
          <BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsEnabled"
                                          Storyboard.TargetName="BackUpSave">
                 <DiscreteBooleanKeyFrame KeyTime="0:0:0" Value="False"/>
          </BooleanAnimationUsingKeyFrames>
         </Storyboard>
       </BeginStoryboard>
     </EventTrigger>
  </StackPanel.Triggers>
</StackPanel>

<强>更新

如果您想要禁用按钮再次点击按钮,请为Button.Click添加另一个事件处理程序,并将其设置为禁用。我更新了xaml代码。


更新2

  

解决方案看起来很麻烦,我怀疑它是否值得   与在Initial,TextChanged中设置IsEnabled属性相比   和点击事件。我错过了更多XAML风格的东西   这些天好吗?

是的,我必须同意 XAML只有解决方案有时很麻烦,可以使用后面的代码轻松完成。特别是在你的情况下,它可以简单地通过钩住一些事件来完成,更重要的是, 没有违反任何MVVM规则,因为你在 背后的代码中执行特定于视图的事情。所以,我认为从背后的代码做ti是没有害处的。

只有XAML解决方案我通常更喜欢,我希望将XAML松散地存储在某个文本文件中,并希望在运行时使用XamlReader.Load() 加载它。

正如我所提到的,动画的优先级高于Dependency属性的本地值setter。因此,一旦TextChanged事件被提升,则值设置为true,并且从后面的代码对该属性的任何进一步更改将不起作用。

但无论如何你可以通过动画设置它来改变代码背后(这里只是为了完整的答案而发布,可能会帮助其他偶然发现这篇文章的人)。这是你如何从代码背后做到的:

private void Button_BackUpSave_Click(object sender, RoutedEventArgs e)
{
   EnableDisableBackUpSaveButton(false);
}

private void EnableDisableBackUpSaveButton(bool value)
{
   BooleanAnimationUsingKeyFrames animation = 
                              new BooleanAnimationUsingKeyFrames();
   DiscreteBooleanKeyFrame keyFrame = new DiscreteBooleanKeyFrame(value, 
                           KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0)));
   animation.KeyFrames.Add(keyFrame);
   BackUpSave.BeginAnimation(Button.IsEnabledProperty, animation);
}

现在,在XAML中,TextChanged上只能有一个XAML触发器。

答案 1 :(得分:2)

您可以使用数据触发器:

<TextBox Name="BackUpTextBox" />
    <Button  Name="BackUpSave" Content="Save">
        <Button.Style>
            <Style TargetType="{x:Type Button}">
                <Setter Property="IsEnabled" Value="True" />
                <Style.Triggers>
                    <DataTrigger Binding="{Binding ElementName=BackUpTextBox, Path=Text, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Value="{x:Null}">
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding ElementName=BackUpTextBox, Path=Text, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}" Value="">
                        <Setter Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Button.Style>
    </Button>

在实际应用程序中虽然您不会在XAML中执行此操作,因为在单元测试中无法测试此行为。