【问题标题】:How to disable button when its Button.CommandProperty is nullButton.CommandProperty 为空时如何禁用按钮
【发布时间】:2010-11-09 20:07:27
【问题描述】:

简短说明

Button.CommandProperty 绑定到 ViewModel 的 SomeObject.SomeCommand 属性。当 SomeObject 的 SomeCommand 属性设置为 null 或整个 SomeObject 属性设置为 null 时,此按钮保持启用状态。在这种情况下如何禁用按钮?

详细解释

我正在使用 MVVM 创建应用程序,其行为类似于浏览器: Main view_model(对应于作为视图的主窗口)有一个 Workspace view_models 列表。每个 Workspace view_model 对应于 windows 的 TabControl 中的 TabPage。 Main view_model 具有 CurrentWorkspace 属性,对应于当前活动的 TabPage。

在主窗口中有一个带有按钮的工具栏,它利用 CurrentWorkspace 提供的命令。例如访问reloading工作区数据实现为:

<Button Name="btReload" Content="Reload" 
        Command="{Binding Path=CurrentWorkspace.ReloadCommand, UpdateSourceTrigger=PropertyChanged}"/>

我试图通过创建 DataTriggers 来完成按钮禁用的任务,但似乎触发器只在第一次起作用,不再起作用:

<Button Name="btReload" Content="Reload" 
        Command="{Binding Path=CurrentWorkspace.ReloadCommand, UpdateSourceTrigger=PropertyChanged}">
    <Button.Style>
        <Style>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=CurrentWorkspace, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
                     <Setter Property="dxb:BarButtonItem.IsEnabled" Value="False"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=CurrentPage.CurrentWorkspace, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Value="{x:Null}">
                    <Setter Property="dxb:BarButtonItem.IsEnabled" Value="False"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

它看起来真的很愚蠢:就像带有无文档客户区的 MS Word,同时在工具栏中有很多可供点击的按钮(具有格式化和其他文档特定的功能)。请帮帮我,:)

附:将 DataContext 绑定到 CurrentWorkspace 的按钮添加到工具栏时,其 DataContextChanged 事件会在窗口中激活或添加或删除工作区选项卡时正确触发。因此,DataTrigger(或通常在 View 中)某处的问题,而不是它的 ViewModel(s)。

更新

我在VS2010上上传了示例项目,存档链接:http://www.filefactory.com/file/b43455e/n/WhatIfCommandIsNull.rar

下面是它的描述。

  1. TextBox 绑定到 ViewModel.Data 属性
  2. 在 Window.DataContext 中分配或删除 ViewModel 可以通过单击两个按钮来完成 - 分别是 btAssignViewModel 和 btRemoveViewModel
  3. ViewModel 公开了两个命令,其中一个将 ViewModel.Data 设置为字符串值,另一个 - 将其设置为 NULL
  4. 这些命令通过其 Button.Command 属性绑定到按钮 btSetData 和 btResetData

如您所见,当 Window.DataContext 设置为 ViewModel 实例时,两个命令都可以正常工作,并且 ResetDataCommand.CanExecute 也可以正常工作(当 ViewModel.Data 为 NULL 时,ResetDataCommand.CanExecute 返回 false 并且按钮 btResetData 被禁用)。一旦 Window.DataContext 设置为 null,最后两个按钮将启用(前两个按钮不绑定任何命令)。

问题在于以声明方式(通过触发器)实现接下来的四个规则:

  • 如果 btAssignViewModel.DataContext 不为 null,则 btAssignViewModel.IsEnabled = false,否则为 true。
  • 如果 btRemoveViewModel.DataContext 为 null,则 btRemoveViewModel.IsEnabled = false,否则为 true。
  • 如果 ViewModel.Data 为 null,则 btSetData.IsEnabled = true,否则为 false。
  • 如果 ViewModel.Data 为 null,则 btResetData.IsEnabled = false,否则为 true。

我认为前两个规则可以使用触发器来实现,后两个 - 使用 DataTriggers。但它们不起作用,所以我从项目中删除了它们。

【问题讨论】:

  • 您可以从您的 ViewModel 中发布您的 Command 属性代码吗?
  • 你是指我的ICommand实现还是ViewModel一个?

标签: wpf binding


【解决方案1】:

这可能有效(取决于您的情况)

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Triggers>
            <Trigger Property="Command" Value="{x:Null}">
               <Setter Property="IsEnabled" Value="false"/>
            </Trigger>
        </Style.Triggers>
    </Style>
</Button.Style>

【讨论】:

  • 不,这行不通。然后我更改或关闭选项卡,按钮闪烁(我将它们放在 32x32 图像上),但仍处于启用状态。
  • 不是在一定的情况下,但一般情况下:当Command值设置为null时需要禁用按钮,不为null时启用。
  • 您使用 ICommand 接口的 CanExecute 部分吗?如果这样做,它应该会自动启用和禁用按钮。
  • 是的,我正在使用 ICommand.CanExecute & 按钮根据 CanExecute 结果正确启用\禁用。收到此消息 8-9 小时后,我将提供非常小的示例项目;现在该上班了,:)
  • 这段代码在我使用你的示例项目时工作得很好。我注意到的唯一奇怪的事情是我必须在运行项目之前重建项目才能使更改生效。
猜你喜欢
  • 1970-01-01
  • 2020-02-18
  • 2015-07-23
  • 2016-05-13
  • 2020-03-13
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
相关资源
最近更新 更多