WPF按钮命令绑定已刷新,但按钮仍然禁用

3
我遇到了一个奇怪的问题,即按钮的命令绑定未被更新...
我有一个使用MvvmLight编写的应用程序,允许用户维护医疗系统列表。这些系统是从模板中构建的(例如,一个模板可能指定两个相机、一个帧抓取器等,并详细说明每个部件应包含的内容)。如果修改了模板,则可以升级系统以使用新模板。系统窗口和模板窗口都是无模式的,因此可以在查看系统时修改模板。如果模板已更新,则模板窗口视图模型会发送消息,以便任何打开的系统窗口可以相应地做出反应。
系统视图包含一个边框,用于在需要升级系统时警告用户。边框的可见性绑定到系统实体上的布尔属性,该属性将系统的修订号与底层模板的最新修订号进行比较。如果它们处于最新模板修订版,则可见性设置为Collapsed,因此他们不会看到内容。
如果系统使用旧版本,则边框可见,内容包含一条信息,告知他们需要升级的需求,以及执行升级的按钮。我有三种情况下的边框和按钮...
1)如果系统在打开窗口时使用过时的版本,则显示边框,并显示按钮。如果修改了模板,则消息会正确更新以显示新编号,并且按钮仍然可见。这是正确的。
2)如果系统在打开窗口时使用最新的模板版本,然后当模板被修订时,边框会正确显示,消息会正确更新,按钮也将启用。这也是正确的,只要我之后关闭系统窗口即可。
3)但是,如果我单击更新按钮,然后在升级系统并隐藏边框之后再次更新模板,则重新显示边框时按钮将被禁用。我尝试从CanExecute方法中删除所有逻辑,并只返回true,以便启用按钮,但它没有起作用。我必须关闭系统窗口并重新打开它才能启用按钮。
我尝试向视图模型添加事件,在更新模板时引发该事件。我在视图中捕获了此事件,并手动刷新了按钮的命令绑定。但是,这并没有导致CanExecute方法被调用,按钮仍然被禁用。
我意识到这有点令人困惑,并且很难在没有看到整个内容的情况下进行调试,但我希望有人能给我一些线索。为了帮助理解,以下是相关代码...
首先,是边框、消息和按钮的XAML...
<Border Visibility="{Binding Converter={StaticResource BoolToVisibilityVC}, Path=NotUsingLatestDhrTemplate, ConverterParameter=true}"
        HorizontalAlignment="Stretch"
        Margin="3"
        Grid.Row="3"
        BorderBrush="Red"
        BorderThickness="2"
        Background="#FFFFEBEB">
  <Grid Margin="3"
        gridHelper:GridHelper.GridRows="*,Auto">
    <WrapPanel>
      <TextBlock Text="This PCR uses template revision "
                  VerticalAlignment="Center" />
      <TextBlock Text="{Binding TemplateRevisionForThisDhr}"
                  VerticalAlignment="Center" />
      <TextBlock Text=", but the current template revision is "
                  VerticalAlignment="Center" />
      <TextBlock Text="{Binding LatestTemplateRevisionForThisPartDefinitionType}"
                  VerticalAlignment="Center" />
      <telerik:RadButton Name="UpdateDhrButton"
                          Click="UpdateDhrButton_OnClick"
                          Command="{Binding Path=DataContext.UpdateDhrCommand, ElementName=DhrViewX}"
                          Margin="0,0,10,0"
                          HorizontalAlignment="Right"
                          VerticalAlignment="Stretch"
                          IsEnabledChanged="UpdateDhrButton_IsEnabledChanged">
        <StackPanel Orientation="Horizontal"
                    Margin="1">
          <Image Margin="0,0,3,0"
                  Width="16"
                  Height="16"
                  Source="/Images;component/Images/battery.png" />
          <TextBlock>Update PCR</TextBlock>
        </StackPanel>
      </telerik:RadButton>
    </WrapPanel>
  </Grid>
</Border>

目前显示CanExecute方法没有任何意义,因为它只包含“return true;”!

看起来边框的可见性和按钮的启用状态之间存在一些奇怪的交互作用,这似乎会覆盖CanExecute方法的结果。

有人有什么想法吗?如果我忘记添加重要内容,请随时询问。提前致谢。


2
如果您正在使用 RelayCommand,也许可以在 CanExecute() 条件更改时尝试调用 UpdateDhrCommand.RaiseCanExecuteChanged(); 或显式地调用刷新。 - Viv
谢谢您的建议,但是并没有起到帮助作用。CanExecute方法正在触发,只是按钮的IsEnabled属性没有被更新。我认为这与父边框的可见性设置为Collapsed有关。这似乎会防止按钮被重新启用,即使CanExecute方法表明它应该被启用。 - Avrohom Yisroel
1个回答

3

虽然我不完全确定问题是什么,但我相当确定,所以我会将它发布出来,以帮助其他人。

问题似乎只发生在某个时候按钮被禁用后。只要命令上有一个CanExecute方法,即使这个方法始终返回true,按钮在绑定过程中仍将暂时禁用。如果包含按钮的边框控件在其可见性设置为Collapsed时发生了这种情况,则无论CanExecute方法返回什么,按钮都不会启用。

我通过删除CanExecute方法并在不想让它被点击时隐藏按钮来解决了这个问题。然后,每次边框变为可见时,我手动将按钮的IsEnabled属性设置为true。

对于这种特定情况,这种解决方式有效,因为按钮的使用基于权限,所以如果他们没有被允许单击它,不让他们看到它就可以了。但在其他情况下仍可能会引起问题,我不确定如何解决。

希望这能帮助到某些人。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接