我有一个奇怪的问题,一个按钮的命令绑定没有更新…
我有一个用MvvmLight编写的应用程序,允许用户维护医疗系统列表。这些系统是根据模板构建的(例如,一个模板可能指定两个摄像头,一个帧采集器等等,以及这些部分应该包含的细节)。修改模板后,系统可以升级为使用新的模板。系统窗口和模板窗口都是非模态的,因此可以在查看系统时修改模板。如果模板被更新了,模板的窗口视图模型会发出一条消息,这样任何打开的系统窗口都可以做出相应的反应。
系统视图包含一个Border,用于在用户需要升级系统时警告用户。边界的可见性被绑定到系统实体上的bool属性,该属性将系统的修订号与底层模板的最新修订号进行比较。如果他们使用的是最新的模板版本,可见性设置为折叠,所以他们看不到内容。
如果系统使用较旧的版本,则边界是可见的,并且内容包含通知他们需要升级的消息,以及执行升级的按钮。我有三种场景使用这个边框和按钮…
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方法的结果。
有人有什么想法吗?如果我在这里忘记添加任何重要的内容,请随时询问。
嗯,虽然我不是100%确定问题是什么,但我很确定我知道,所以我会把它贴出来,以防它对其他人有帮助。
这个问题似乎只发生在按钮被禁用之后。似乎只要我在命令上有一个CanExecute方法,那么即使它总是返回true,该按钮仍然会在绑定过程中暂时禁用。如果当包含按钮的边框控件的可见性设置为折叠时发生这种情况,那么按钮将不会被启用,无论CanExecute方法返回什么。
我通过删除CanExecute方法来解决这个问题,当我不想被点击时隐藏按钮。然后,每次使边框可见时,我手动将按钮的IsEnabled属性设置为true。
这在这个特殊的场景中是有效的,因为按钮的使用是基于权限的,所以如果他们不被允许点击它,那么不让他们看到它是可以的。但在其他情况下,它仍然会引起问题,我不确定如何解决它。