【问题标题】:Connect ViewModel to Model将 ViewModel 连接到模型
【发布时间】:2013-07-02 12:56:02
【问题描述】:

我正在开发一个应用程序,并花了很长时间为以下问题寻找解决方案。我已经尝试了几件事,但我不确定解决它的最佳方法是什么。

我有一个视图、视图模型和模型的设置。 ViewModel 包含一个模型集合,用户可以从中选择一个特定的模型(集合可以为空,这使得所选模型为空)。

视图由一个组合框组成,它允许用户从模型集合中选择一个模型。选定的模型随后将显示在视图中(带有各种控件,例如树视图、标签……)。

这是模型(为了解释,我将保持简单):

public Model {
    private int id;
    private String name;

    public Model(_id, _name) {
        id = _id;
        name = _name;
    }

    public int ID {
        get { return id; }
        set { id = value; }
    }
    public String Name {
        get { return name; }
        set { name = value; }
    }
}

还有 ViewModel:

public ViewModel : INotifyPropertyChanged {
    private ObservableCollection<Model> models = new ObservableCollection<Model>();
    private Model selectedModel;

    public ViewModel() { }

    public Model SelectedModel {
        get { return selectedModel; }
        set { 
            selectedModel = value; 
            NotifyChanged("SelectedModel");   
        }
    }
    public Model ModelCellection {
        get { return models; }
        set { 
            models = value; 
            NotifyChanged("ModelCellection");   
        }
    }

    public void addModel(Model newModel) {
        models.Add(newModel);
    }

    //variant A
    public int ID {
        get { return (selectedModel == null) ? 0 : selectedModel.ID; }
        set {
            if(selectedModel == null)
                return; 
            selectedModel.ID = value; 
            NotifyChanged("ID");   
        }
    }
    public String Name {
        get { return (selectedModel == null) ? 0 : selectedModel.Name; }
        set {
            if(selectedModel == null)
                return; 
            selectedModel.Name = value; 
            NotifyChanged("Name");   
        }
    }

    //variant B (the attributes of the model will be copied when the selected model changes)
    public void changeSelectedModel(Model newSelectedModel) {
        Name = newSelectedModel.Name;
        Id = newSelectedModel.Id;
    }
    private int id = 0;
    private String name = String.Empty;
    public int ID {
        get { return id; }
        set {
            id = value; 
            NotifyChanged("ID");   
        }
    }
    public String Name {
        get { return name; }
        set {
            name = value; 
            NotifyChanged("Name");   
        }
    }
}

我的问题很简单:如何通过 ViewModel 访问模型的相关公共属性?

到目前为止我尝试过的解决方案是:

  • 变体 A:只需更改所选模型并使用代理属性来访问模型的属性(问题:当所选模型更改时,视图不会更新,因为 ViewModel 的 Name 和 Id 属性不会引发一个 PropertyChanged 事件)
  • 变型B:更改所选模型时复制模型的相关属性(问题:我必须复制模型的属性)

在与 wpf 聊天中的一些人交谈后,我从变体 B 切换到变体 A,但我不知道如何解决所选模型更改时更新视图的问题?还是您更愿意建议使用完全不同的方法来解决这个问题?

【问题讨论】:

  • 我会选择变体 C:创建一个 ViewModelItem,就属性而言,它将对应于 Model,但也将处理属性通知、验证等。然后,在“主' ViewModel 使用上述 ViewModelItems 的集合。您可以使用 ValueInjecter 或 AutoMapper 等工具在模型和视图模型之间进行映射...

标签: c# mvvm model viewmodel


【解决方案1】:

不知道如何解决所选模型发生变化时更新视图的问题?

只需在您的 SelectedModel 定义中引发 PropertyChanged 事件

public Model SelectedModel {
        get { return selectedModel; }
        set { 
            selectedModel = value; 
            NotifyChanged("SelectedModel");   
            NotifyChanged("ID");
            NotifyChanged("Name");
        }
    }

【讨论】:

  • 我不敢相信我没有想到这一点 - 谢谢 :)。这种访问模型属性的方法是“最先进的”吗?
【解决方案2】:

你必须在你的模型中实现INotifyPropertyChanged。 你的代码看起来像。

你的 Model.cs

public Model:INotifyPropertyChanged
 {
private int id;
private String name;

public Model(_id, _name) 
  {
    id = _id;
    name = _name;
   }

public int ID {
    get { return id; }
    set { id = value;  NotifyChanged("ID");}
    }
public String Name
   {
    get { return name; }
    set { name = value;  NotifyChanged("Name");}
   }
}

你的 ViewModel.cs

 public ViewModel 
 {
  private ObservableCollection<Model> models = new ObservableCollection<Model>();
  private Model selectedModel;

  public ViewModel() { }

  private Model _SelectedModel ;
  public Model SelectedModel 
  {
    get { return _SelectedModel??(_SelectedModel=new SelectedModel());}
    set { _SelectedModel  = value;}
   }
 }

如果属性已被更改,它将以芳香方式通知,因为在 ViewModel 中存在模型对象。

【讨论】:

    【解决方案3】:

    你必须像这样设置你的属性

    public void changeSelectedModel(Model newSelectedModel) 
     {
        SelectedModel.Name = newSelectedModel.Name;
        SelectedModel.Id = newSelectedModel.Id;
     }
    

    它会通知。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多