使用TextBox UpdateSourceTrigger和PropertyChanged时出现问题

时间:2013-11-05 15:03:37

标签: wpf vb.net mvvm binding updatesourcetrigger

目标

我希望在文本框btnRefresh中包含某些内容时使用按钮tbMachineNo(使用MVVM标准)。


项目摘要

在这一个上和我一起,我会试着详细解释一下。我有一个:

Window.xaml

<TextBox Text="{Binding Inspection.Machine.MachineNumber, UpdateSourceTrigger=PropertyChanged}" />
<Button Command="{Binding RefreshMachineNo}" />

InspectionViewModel.vb

它具有InspectionModel的属性并包含多种方法。一个是我的ICommand在我的构造函数中被执行(这是因为CanUpdate方法而禁用/启用我的文本框的内容)

Public Class InspectionViewModel
    Private _Inspection As InspectionModel
    Private _RefreshMachineNo As ICommand

    Public Property Inspection As InspectionModel
        Get
            Return _Inspection
        End Get
        Set(value As InspectionModel)
            _Inspection = value
        End Set
    End Property

    Public Sub New()
        _Inspection = New InspectionModel("Version", "Title of machine", "Model", "Owner", "Department", Date.Now, New MachineModel)
        RefreshMachineNo = New RefreshMachineNumberCommand(Me) 'Calls the CanUpdate, and if it returns true, it executes FetchMachineDetails()
    End Sub

    Public Property RefreshMachineNo As ICommand
        Get
            Return _RefreshMachineNo
        End Get
        Set(value As ICommand)
            _RefreshMachineNo = value
        End Set
    End Property

    Public ReadOnly Property CanUpdate As Boolean
        Get
            If Inspection Is Nothing Then
                Return False
            End If
           Return Not String.IsNullOrWhiteSpace(Inspection.Machine.MachineNumber)
        End Get
    End Property

    Public Sub FetchMachineDetails()
        Dim MachineNo As String = Inspection.Machine.MachineNumber
    End Sub
End Class

这很好用,代码在应该执行时执行。现在来看看我的InpsectionModel。

RefreshMachineNumberCommand

Public Class RefreshMachineNumberCommand
    Implements ICommand

    Private _viewModel As InspectionViewModel

    Public Sub New(ByVal viewModel As InspectionViewModel)
        _viewModel = viewModel
    End Sub

    Public Event CanExecuteChanged(sender As Object, e As System.EventArgs) Implements System.Windows.Input.ICommand.CanExecuteChanged

    Public Function CanExecute(parameter As Object) As Boolean Implements System.Windows.Input.ICommand.CanExecute
        Return _viewModel.CanUpdate()
    End Function

    Public Sub Execute(parameter As Object) Implements System.Windows.Input.ICommand.Execute
        _viewModel.FetchMachineDetails()
   End Sub
End Class

InspectionModel.vb

这个类继承了我的ObservableObject,它实现了INotifyPropertyChanged。因此,理论上,只要我的属性MachineNumber在检查对象Machine中发生更改,它就会触发UpdateSourceTrigger=PropertyChanged

Public Class InspectionModel
    Inherits ObservableObject

    Private _Version As String
    Private _Title As String
    Private _Model As String
    Private _InspectionOwner As String
    Private _Department As String
    Private _DateEntry As Date
    Private _Machine As MachineModel

    Public Property Version As String
        Get
            Return _Version
        End Get
        Set(value As String)
            _Version = value
            Notify("Version")
        End Set
    End Property
    Public Property Title As String
        Get
            Return _Title
        End Get
        Set(value As String)
            _Title = value
            Notify("Title")
        End Set
    End Property
    Public Property Model As String
        Get
            Return _Model
        End Get
        Set(value As String)
            _Model = value
            Notify("Model")
        End Set
    End Property
    Public Property InspectionOwner As String
        Get
            Return _InspectionOwner
        End Get
        Set(value As String)
            _InspectionOwner = value
            Notify("InspectionOwner")
        End Set
    End Property
    Public Property Department As String
        Get
            Return _Department
        End Get
        Set(value As String)
            _Department = value
            Notify("Department")
        End Set
    End Property
    Public Property DateEntry As Date
        Get
            Return _DateEntry
        End Get
        Set(value As Date)
            _DateEntry = value
            Notify("DateEntry")
        End Set
    End Property
    Public Property Machine As MachineModel
        Get
            Return _Machine
        End Get
        Set(value As MachineModel)
            _Machine = value
            Notify("Machine")
        End Set
    End Property

    Public Sub New(ByVal Version As String, ByVal Title As String, ByVal Model As String, ByVal InspectionOwner As String, ByVal Department As String, ByVal DateEntry As Date, ByVal Machine As MachineModel)
        Me.Version = Version
        Me.Title = Title
        Me.Model = Model
        Me.InspectionOwner = InspectionOwner
        Me.Department = Department
        Me.DateEntry = DateEntry
        Me.Machine = Machine
    End Sub
End Class

问题

当文本框填充了字符或空白时,我没有理解如何启用/禁用我的按钮控件。我的ICommand的CanUpdate是当前控制它的,只在加载构造函数时执行一次。

这是有道理的,但我不知道如何在不放置代码的情况下使Textchanged问题发挥作用。我希望能够使用MVVM

来做到这一点

修改

我将Textbox绑定到另一个字段,该字段与Inspection对象中的相同属性绑定。当我在文本框中输入时,我可以看到其他字段被修改...所以UpdateSourceTrigger正在工作但是当我输入文本时我无法启用按钮。

2 个答案:

答案 0 :(得分:1)

  1. 确保将UpdateSourceTrigger设置为PropertyChanged
  2. 在您的媒体资源制定者中,请致电RefreshMachineNo.RaiseCanExecuteChanged()
  3. RaiseCanExecuteChanged是在DelegateCommand和RelayCommand上找到的标准方法。希望您为命令使用行业标准ICommand实现之一。

答案 1 :(得分:0)

我的问题出现在我的RefreshMachineNumberCommand.vb课程中。

更具体地说,我的CanExecuteChanged事件没有处理CommandManager。以下是我为解决这个问题所做的工作:

Public Custom Event CanExecuteChanged As EventHandler Implements ICommand.CanExecuteChanged
    AddHandler(ByVal value As EventHandler)
        AddHandler CommandManager.RequerySuggested, value
    End AddHandler

    RemoveHandler(ByVal value As EventHandler)
        RemoveHandler CommandManager.RequerySuggested, value
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        CanExecute(sender)
    End RaiseEvent
End Event

有关详细信息,this post帮助了我很多!