我有一个名为Client的视图类,它的视图模型是ClientViewModel。 ClientViewModel有一个模型对象ClientInfo。此ClientInfo [Model]是复杂对象,具有名为Client&的Model类的属性。 ClientProfile。
我在View中绑定了我的UI元素的属性,如下所示(我使用xxx.yyy.zzz来到属性)
<Label Content="First Name:" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Left" Margin="3,5,0,4" VerticalAlignment="Center" Height="26" Width="70" />
<TextBox Grid.Column="1" Grid.Row="1" Height="24" HorizontalAlignment="Left" Margin="3,7,0,4" Name="firstNameTextBox" Text="{Binding Path=ClientInfo.Client.FirstName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
<Label Content="Last Name:" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Left" Margin="3,3,0,6" VerticalAlignment="Center" Height="26" Width="69" />
<TextBox Grid.Column="1" Grid.Row="2" Height="24" HorizontalAlignment="Left" Margin="3,5,0,6" Name="lastNameTextBox" Text="{Binding Path=ClientInfo.Client.LastName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" VerticalAlignment="Center" Width="120" />
..
<Button Content="Save" Height="24" Grid.Column="0" Grid.Row="0" Command="{Binding SubmitCommand}" Cursor="Hand" Margin="549,10,10,0" Name="button1" VerticalAlignment="Top" Width="75" RenderTransformOrigin="-0.137,-1.804" />
ClientViewModel:
[Export(typeof(ClientViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class ClientViewModel : NotificationObject
{
private readonly IClientService clientService;
private ClientInfo clientInfoModel;
private string currentState;
public DelegateCommand<object> SubmitCommand { get; private set; }
public DelegateCommand<object> UpdateCommand { get; private set; }
public DelegateCommand<object> LoadCommand { get; private set; }
[Import]
public ClientInfo ClientInfoModel
{
get { return this.clientInfoModel; }
set
{
clientInfoModel = value;
this.RaisePropertyChanged(() => this.ClientInfoModel);
}
}
[ImportingConstructor]
public ClientViewModel(IClientService clientService)
{
this.clientService = clientService;
this.SubmitCommand = new DelegateCommand<object>(this.Submit);
this.UpdateCommand = new DelegateCommand<object>(this.Update);
this.LoadCommand = new DelegateCommand<object>(this.Load);
}
private void Load(object obj)
{
throw new NotImplementedException();
}
private void Update(object obj)
{
//update
throw new NotImplementedException();
}
private void Submit(object obj)
{
string s = this.ClientInfoModel.ClientBasic.FirstName;//<--- this where i get the NPE exception
}
public string ViewName
{
get { return "Client Details"; }
}
public string CurrentState
{
get
{
return this.currentState;
}
set
{
if (this.currentState == value)
{
return;
}
this.currentState = value;
this.RaisePropertyChanged(() => this.CurrentState);
}
}
public bool CanSubmit
{
get { return true; }
}
public void Submit()
{
this.CurrentState = "Submitting";
//this.clientRepository.SaveClientAsync(this.ClientInfoModel, result => { SaveClient(); });
}
private object SaveClient()
{
this.CurrentState = "Saving";
return null;
}
}
ClientInfo(Model):
public class ClientInfo : DomainObject
{
public Client ClientBasic { get; set; }
public ClientProfile Profile { get; set; }
}
客户(型号):
public class Client : DomainObject
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
....
}
在提交命令调用中:
private void Submit(object obj)
{
ClientInfo ci = new ClientInfo();
ci.Client <-- (here i would want to get the new Client obj assigned from properties?)
ci.ClientProfile <---(same as above)
}
在保存命令中,视图有提交按钮以保存。我必须保存调用某些服务的新客户端对象。
这里的问题是,我需要用新的Client()&amp ;;填写ClientInfo模型。新的ClientProfile()对象。我怎么能用这个设置做到这一点。
答案 0 :(得分:1)
我可以在这里看到几点,我会做的不同。但是,一般情况下,你发布的内容一切都很好,你没有发布的内容肯定有些错误。请发布完整的ViewModel类,并解释如何将M传递给VM,将VM传递给V,我将再看看它。
如果执行ClientInfo
时Submit(..)
为空,则表示您的ViewModel没有模型。在ViewModel上分配ClientInfo
时,一定有问题。尝试在ClientInfos
set accessor中设置断点,看看它是否只设置一次。尝试在例如FirstName
的set访问器中设置断点,并在UI中输入名称时查看它是否被命中。输出控制台中是否显示任何BindingErrors?
话虽如此,你确定要做你想做的事吗?如果您创建新的ClientInfo
类,并从另一个Client
类分配属性ClientProfile
和ClientInfo
,则您的两个ClientInfo
对象指向完全相同的{ {1}}和Client
对象。由于ClientProfile
只有这两个属性,我可以想到你为什么会复制ClientInfo
对象。你可以很好地使用原始对象,这是你的ViewModel模型......
其次,你的ViewModel直接暴露了Model,这实际上并不是ViewModel的重点,特别是当你最终得到像
这样的链式绑定时ClientInfo
ViewModels核心竞争力是聚合数据并允许从View轻松绑定。我将在ViewModel上公开Text="{Binding Path=ClientInfo.Client.FirstName}"
,FirstName
等属性,让ViewModel找出从哪里获取数据并将数据推送到。请记住,您希望独立于后台的任何实现细节保持View。
也许这两个建议已经解决或完全避免了这个问题。否则请随时发布更多上下文,我会再看看。
修改强>
在你的ViewModel中,我希望像
这样的东西LastName
您注入了服务,但是在哪里初始化ClientInfoModel = clientService.GetClientInfo(...);
?