【问题标题】:Proper using of MVVM and Commands正确使用 MVVM 和命令
【发布时间】:2015-04-14 08:58:48
【问题描述】:

ICommand接口如何与MVVM配合使用?

鉴于我添加了DataContext(这是我的ViewModel : INotifyPropertyChanged)并将控件的属性 - 进度条的IsInterminate - 绑定到我的ViewModel 的属性。我的ViewModel 的这个属性不是静态的,所以我需要ViewModel 的实例。

我的问题是:我应该如何在命令的方法中更新这个ViewModel 实例(属性绑定到视图的进度条)(这个方法是ViewModel)?

<StatusBar Grid.Row="1">
    <StatusBar.DataContext>
        <viemodel:EventsViewModel x:Name="evm"/>
    </StatusBar.DataContext>
    <Label x:Name="lbStatusLabel" Width="70" Height="40" Content="{Binding EventsCollection.Count}"/>
    <Separator />
    <ProgressBar x:Name="pbProgress" Width="300" Height="40" IsIndeterminate="{Binding Pennding}"/>
</StatusBar>

class EventsViewModel : ViewModel
{
    private static FWatch fw;
    private static string fileName;
    private static string pathToFile;
    private static string pathToDirectory;

    public EventsViewModel()
    {
        _startCommand = new RelayCommand(OpenFileCommand);
    }

    private ICommand _startCommand;
    public ICommand StartCommand
    {
        get { return _startCommand; }
    }

    private static ObservableCollection<Event> _eventsCollection = new ObservableCollection<Event>();
    public static ObservableCollection<Event> EventsCollection
    { 
        get { return _eventsCollection; }
    }

    private static string _buttonContent = "Open file";        
    public string ButtonContent
    {
        get { return _buttonContent; }
        set
        {
            _buttonContent = value;
            NotifyPropertyChanged();
        }
    }

    private bool _pending = false;
    public bool Pennding
    {
        get { return _pending; }
        set
        {
            _pending = value;
            NotifyPropertyChanged();
        }
    }

    private void OpenFileCommand()
    { 
        // Here I want to update field _pennding - is it right? Or should I delegate it?
        // Should I update `Pendding` property of `ViewModel` where is command's method or I should do it in behind-code of view?
    }
} 

【问题讨论】:

  • 是的,它是正确的,OpenFileCommand 已经是传递给 RelayCommand 的委托,这正是它应该使用的方式。使用 RelayCommand 时要注意的一件事(我猜它来自 MVVMlight 或原始 Josh Smith 实现)它应该在 ViewModel 被释放时设置为 null,因此 ViewModel 应该实现 IDisposable,如果你使用来自 MS Prism 的 DelegateCommand 那么你不会不需要实现 IDisposable 是否在内部对事件处理程序使用弱引用
  • @AwkwardCoder 但是如何在此方法中更改 Pennding 属性?
  • 如下图@XAML Lover
  • 你应该有类似 NotifyPropertyChanged("Pennding");请注意,我在此处的代码中具有与您的代码相同的属性名称,而不是“待定”。
  • @AwkwardCoder 但它对我不起作用。没有什么变化。我想我应该在进度条数据上下文中使用 x:Name - 这给了我 EventViewModel 的实例。

标签: c# wpf xaml mvvm command


【解决方案1】:

您应该从命令处理程序中设置您的“待定”属性。在您的情况下,它是 OpenFileCommand。

private void OpenFileCommand()
{ 
     this.Pending = true;
}

【讨论】:

    【解决方案2】:

    您必须使用一些命令基础架构组件。有几种可用。 例如 MVVM Light 就是一个不错的选择。 在这里查看一些提示: How to use RelayCommand with the MVVM Light framework

    但您需要在表单上添加一个按钮,并将其绑定到命令以触发ViewModel 上的操作。

    Pending 应该在ViewModel 中进行操作。绑定负责其余的工作。 要提出“属性更改”通知,我使用:

    this.OnPropertyChanged(() => Breedte);
    

    即在最终引发的事件中传递更改的属性。我在你的代码中没有看到。 你至少需要类似上面的东西或

    NotifyPropertyChanged("propertyName");
    

    否则框架不知道发生了什么变化以及如何调整 GUI。

    【讨论】:

      【解决方案3】:

      现在我知道了。

      在 xaml 中使用 datacontext 创建实例。我使用 dataconytext 标签 3 次,我有 3 个我的 viemodel 实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-06
        • 2013-11-22
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-07
        • 1970-01-01
        相关资源
        最近更新 更多