【问题标题】:Simple MVVM binding issue简单的 MVVM 绑定问题
【发布时间】:2012-10-16 23:47:59
【问题描述】:

我有一个文本框和一个按钮。 Button Command 应该改变绑定到 TextBox 的属性。

但我在命令执行后看不到任何视觉变化。 我认为与 wpf 绑定有关的简单问题

请帮我解决这个问题

应用来源:

<UserControl.DataContext>
    <local:SampleViewModel />
</UserControl.DataContext>
<Grid>
    <StackPanel>
        <TextBox Height="23" Width="120" Text="{Binding MyName}"  />
        <Button Content="Click" Command="{Binding ButtonCommand}" />
    </StackPanel>
</Grid>

视图模型:

Private _myName As String
Public Property MyName As String
  Get
    Return _myName
  End Get
  Set(value As String)
    _myName = value
      OnPropertyChanged("MyName")
  End Set
End Property

Public _buttonCommand As DelegateCommand
Public ReadOnly Property ButtonCommand As DelegateCommand
Get
  Return If(_buttonCommand IsNot Nothing, _buttonCommand, 
  New DelegateCommand(AddressOf Execute, AddressOf CanExecute))
End Get
End Property

Private Sub Execute()
  MyName = "Executed"
End Sub

Private Function CanExecute() As Boolean
  Return True
End Function

Public Event PropertyChanged As PropertyChangedEventHandler
Private Sub OnPropertyChanged(propertyName As String)
  RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub

【问题讨论】:

  • 您是否尝试在 Execute() 中设置断点?
  • 能否尝试在Execute 设置断点并查看它是否已执行?
  • MyName 不需要是 Observable 的吗?
  • @Garrett:我无法重现此问题。这是您实际代码的精简版吗?
  • @sixlettervariables :我也无法重现该问题。我猜其他地方有问题。

标签: wpf vb.net data-binding mvvm


【解决方案1】:

执行以下操作:

1。 类主窗口 实现 INotifyPropertyChanged

2 。在 Public Sub New() 中确保你写 Me.DataContext = Me 来设置 DataContext

注意:如果您使用 ViewModel 并在 XAML 中设置,请忽略第 2 步

3 .像这样修改 ProperyChanged: Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged

只有在implementing INotifyPropertyChanged correctly 之后,Binding 才会在 PropertyChanged 事件之后正确刷新 MyName 属性

【讨论】:

  • 他的代码不起作用,我能够在 VS 2010 上重现他的问题。以下解决了我电脑上的问题。
  • 我无法用他的 VB 和 XAML (VS12) 重现他的问题。我想知道他是否从类声明中省略了“Implements INotifyPropertyChanged”。这是我认为他所做的代码的唯一部分。假设 OP 遗漏了 INPC 标头代码,我已经删除了我的反对票。
  • 我同意当他使用 ViewModel 并在 XAML 中设置时更改 DataContext 是不必要的。由于他没有提到他是否实现了 INotifyPropertyChanged,所以我详细介绍了如何解决 CodeBehind 的问题。我会在答案中注明
  • 我发现了一个问题部分:我使用 SimpleMVVM 框架和 ViewModelBase 作为我的视图模型的基类。实现 INotifyPropertyChanged 接口后一切正常。感谢大家的帮助。
【解决方案2】:

这是一个适用于您的确切 XAML 的代码(我从 http://wpftutorial.net/DelegateCommand.html 获取了 DelegateCommand 实现)对不起,它是 C#,我真的不喜欢 VB:D

public class DelegateCommand : ICommand
{
    private readonly Predicate<object> _canExecute;
    private readonly Action<object> _execute;

    public event EventHandler CanExecuteChanged;

    public DelegateCommand(Action<object> execute)
        : this(execute, null)
    {
    }

    public DelegateCommand(Action<object> execute,
                   Predicate<object> canExecute)
    {
        _execute = execute;
        _canExecute = canExecute;
    }

    public virtual bool CanExecute(object parameter)
    {
        if (_canExecute == null)
        {
            return true;
        }

        return _canExecute(parameter);
    }

    public virtual void Execute(object parameter)
    {
        _execute(parameter);
    }

    public void RaiseCanExecuteChanged()
    {
        if (CanExecuteChanged != null)
        {
            CanExecuteChanged(this, EventArgs.Empty);
        }
    }
}

public class SampleViewModel : INotifyPropertyChanged
{
    // Create the OnPropertyChanged method to raise the event 
    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;

    public DelegateCommand _buttonCommand;
    public DelegateCommand ButtonCommand
    {
        get
        {
            if (_buttonCommand == null)
            {
                _buttonCommand = new DelegateCommand(Execute);
            }
            return _buttonCommand;
        }
    }

    public void Execute(object o)
    {
        MyName = "executed";
    }

    public string MyName { get { return _myName; } set { _myName = value; OnPropertyChanged("MyName"); } }

    private string _myName;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 2014-02-26
    • 2018-10-20
    • 2011-09-15
    • 2011-03-20
    相关资源
    最近更新 更多