【发布时间】:2021-09-29 08:01:49
【问题描述】:
Xamarin 表单和 MVVM 的新手-如果我想到这个错误,请原谅我。
我的应用程序中的文件包括:
- 模型(保存我创建的库中对象的自动属性)
- 视图(每个元素都被初始化为默认值,用户可以选择更改这些值。每个元素都绑定到它在视图模型中的相对属性。)
- View-model(包含绑定属性,使用调用 INotifyPropertyChanged 方法 OnPropertyChanged 的 SetProperty 方法对每个属性进行适当设置。
- 界面(包含我的服务的签名)
- 服务(构造函数为我的模型设置默认值。接口中签名的具体实现。提供从视图模型访问模型属性的方法)
从视图绑定到视图模型很好。问题是,我无法弄清楚如何从我的视图模型中更新模型中的相应属性。如果我理解正确,SetProperty 方法以发布-订阅方式与视图一起工作——允许视图通知任何更改并相应地更新。但是,我是否也使用此方法来更新我的服务中的属性?我尝试创建一个单独的方法,与 SetProperty 方法同时调用以更新模型属性值,但这导致 SetProperty 方法没有被调用。我考虑过实现一个命令,但选择器没有绑定到一个命令。欢迎任何建议!简化代码如下:
型号:
public class Model
{
public Device ModelDevice { get; set; }
}
查看:
<RefreshView x:DataType="local:ConfigViewModel" Command="{Binding LoadModelCommand}" IsRefreshing="{Binding IsBusy, Mode=TwoWay}">
<ScrollView Padding="10">
<StackLayout>
<Label Text="Address Type" />
<Picker ItemsSource="{Binding AddressTypes}" SelectedItem="{Binding AddressType, Mode=TwoWay}">
<Picker.Items></Picker.Items>
</Picker>
</StackLayout>
</ScrollView>
</RefreshView>
视图模型:
private AddressType _myAddressType;
public AddressType MyAddressType;
{
get => _myAddressType;
set => SetProperty(ref _myAddressType, value);
}
private ObservableCollection<AddressType> _myAddressTypes;
public ObservableCollection<AddressType> MyAddressTypes;
{
get => _myAddressTypes;
set => SetProperty(ref _myAddressTypes, value);
}
public Command LoadModelCommand { get; }
public ConfigViewModel()
{
Title = "Configuration";
LoadModelCommand = new Command(async () => await ExecuteLoadModelCommand());
}
async Task ExecuteLoadModelCommand()
{
IsBusy = true;
try
{
//The service is injected into my BaseViewModel, making it accessible here
var model = await Service.GetModelAsync();
// ----- Device Properties
MyAddressTypes = model.ModelDevice.AddressTypes;
MyAddressType = model.ModelDevice.AddressType;
}
catch (TaskCanceledException tcex)
{
Debug.WriteLine(tcex);
}
finally
{
IsBusy = false;
}
}
服务:
public class Service : IService
{
private Model _aModel;
public Service()
{
//Default View Values
_aModel = new Model {
ModelDevice = new Device("192.168.0.000"),
};
// ----- Device Properties
_aModel.ModelDevice.Label = "L18";
_aModel.ModelDevice.Simulate = false;
_aModel.ModelDevice.AddressType = MOD_6_DIGIT;
//----- Device Address type
foreach (var addressType in Enum.GetValues(typeof(MBClient.AddressType)))
__aModel.ModelDeviceAddressTypes.Add((AddressType)addressType);
}
public async Task<Model> GetModelAsync()
{
return await Task.FromResult(_aModel);
}
【问题讨论】:
-
通常会有某种动作——比如用户选择“保存”或“下一步”,您可以在其中使用 VM 属性更新您的模型,然后保存它。但是没有一种方法可以做到这一点,这取决于您的应用是如何设计和实现的
-
@Jason 我最终调用了我的异步任务以从我的 VM 中的一个方法更新模型,并从属性设置器中调用该方法。但我很感激你的建议!
标签: c# xaml xamarin.forms mvvm dependency-injection