gpt4 book ai didi

c# - 更新 subview 模型时如何更新父 View 模型

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:53 24 4
gpt4 key购买 nike

在我的第一个 View 模型(重命名为 MainViewModel)中,我有一个 ActionViewModel 列表。在我的 xaml 中,我有一个绑定(bind)到列表的列表框,在列表框中,我有一个绑定(bind)到 ActionViewModel 属性的模板。

到目前为止一切顺利,一切正常。选择其中一个列表项时,我导航到 ActionViewModel 并传递 id。ActionViewModel 从内存中的静态列表中检索信息,MainViewModel 也从中检索信息以创建 actionviewmodel 列表。

到目前为止仍然很好,我可以编辑属性,所有绑定(bind)都工作正常,我很高兴。通过单击保存按钮,信息被收集并存储在静态列表中。当我按下后退按钮时,我返回到列表,但不幸的是,显示的值仍然相同,有什么方法可以发送命令以重新加载列表中的项目?要传递一个完整的 View 模型作为对新 ActionViewModel 的引用?或者告诉父级“您列表中的这个 View 模型已更新”的一些属性?

我确信上面的文字有点令人困惑,所以这里有一些代码来澄清一下(希望如此)

MainViewModel.cs

private List<ActionViewModel> _actionViewModels;
public List<ActionViewModel> ActionViewModels
{
get { return _actionViewModels; }
set { _actionViewModels = value; RaisePropertyChanged(() => ActionViewModels); }
}


private Cirrious.MvvmCross.ViewModels.MvxCommand<int> _navigateToAction;
public System.Windows.Input.ICommand NavigateToAction
{
get
{
_navigateToAction = _navigateToAction ?? new Cirrious.MvvmCross.ViewModels.MvxCommand<int>((action) => NavigateToTheDesiredAction(action));
return _navigateToAction;
}
}

private void NavigateToTheDesiredAction(int action)
{
ShowViewModel<ActionViewModel>(new { id = action });
}

// Get DTOs from server or from cache and fill the list of ActionViewModels
public async Task Load()
{
ActionService actionService = new ActionService();

List<ActionViewModel> actionViewModels = new List<ActionViewModel>();

MyActions = await actionService.GetMyActions();
foreach (ActionDTO action in MyActions)
{
ActionViewModel actionViewModel = new ActionViewModel();
await actionViewModel.Load(action.id);
actionViewModels.Add(actionViewModel);
}

ActionViewModels = actionViewModels;
}

ActionViewModel.cs

public int ID
{
get { return TheAction.id; }
set { TheAction.id = value; RaisePropertyChanged(() => ID); }
}

public string Title
{
get { return TheAction.Title; }
set { TheAction.Title = value; RaisePropertyChanged(() => Title); }
}

public async Task Load(int actionId)
{
ActionDTO TheAction = await actionService.GetAction(actionId);
this.ID = TheAction.id;
this.Title = TheAction.Title;
}

private Cirrious.MvvmCross.ViewModels.MvxCommand _save;
public System.Windows.Input.ICommand Save
{
get
{
_save = _save ?? new Cirrious.MvvmCross.ViewModels.MvxCommand(PreSaveModel);
return _save;
}
}

private void PreSaveModel()
{
SaveModel();
}

private async Task SaveModel()
{
ValidationDTO result = await actionService.SaveAction(TheAction);
}

Action 服务.cs

public static List<ActionDTO> AllActions = new List<ActionDTO>();

public async Task<ActionDTO> GetAction(int actionId)
{
ActionDTO action = AllActions.FirstOrDefault(a => a.id == actionId);
if (action == null)
{
int tempActionId = await LoadAction(actionId);
if (tempActionId > 0)
return await GetAction(actionId);
else
return new ActionDTO() { Error = new ValidationDTO(false, "Failed to load the action with id " + actionId, ErrorCode.InvalidActionId) };
}
return action;
}

private async Task<int> LoadAction(int actionId)
{
ActionDTO action = await webservice.GetAction(actionId);
AllActions.Add(action);
return action.id;
}

public async Task<ValidationDTO> SaveAction(ActionDTO action)
{
List<ActionDTO> currentList = AllActions;
ActionDTO removeActionFromList = currentList.FirstOrDefault(a => a.id == action.id);
if (removeActionFromList != null)
currentList.Remove(removeActionFromList);

currentList.Add(action);
AllActions = currentList;
return await webservice.SaveAction(action);
}

最佳答案

我可以想到 3 种方法可以让您做到这一点。

  1. ActionService可以在数据更改时发出某种通知。一种简单的方法是使用 MvvmCross Messenger 插件。这是 CollectABull 服务在 CollectionService.cs 中的工作方式在 N+1 天的 mvvmcross 视频中(有关更多信息,请观看 http://mvvmcross.wordpress.com 中的 N=13)

    这是我通常使用的方法。它的开销很低,使用 WeakReference s(所以不会泄漏内存),它很容易扩展(任何对象都可以监听变化),它鼓励 ViewModel 和 Model 对象的松散耦合

  2. 你可以实现某种 Refresh ViewModel 列表中的 API,可以从适当的 View 事件(例如 ViewDidAppearOnNavigatedToOnResume)中调用它。

    我通常不使用这种方法来刷新已知数据,但我用它来启用/禁用资源密集型对象 - 例如定时器

    对于特定形状的模型数据(尤其是它更改的频率),我可以想象这种方法可能比信使方法更有效的场景。

  3. 您可以扩展 INotifyPropertyChanged 的使用范围和 INotifyCollectionChanged回到你的模型层。

    我已经这样做了几次,对我来说效果很好。

    如果您确实选择了这种方法,请注意确保所有 View 都使用 WeakReference 订阅更改事件。订阅,例如 MvvmCross 绑定(bind)中使用的订阅 - 请参阅 WeakSubscription .如果您不这样做,那么即使 UI 本身已删除 View ,模型也可能会导致 View 保留在内存中。

关于c# - 更新 subview 模型时如何更新父 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18405470/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com