1

我有一个名为 Client 的视图类,它的视图模型是 ClientViewModel。ClientViewModel 有一个模型对象 ClientInfo。此 ClientInfo [Model] 是复杂对象,它具有称为 Client 和 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" />

客户端视图模型:

[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;
    }
}

客户信息(型号):

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() 和新的 ClientProfile() 对象填充 ClientInfo 模型。我有这个设置怎么能做到这一点。

4

1 回答 1

1

我可以在这里看到一些我会做不同的点。但是,总的来说,您发布的一切都很好,您未发布的部分肯定有一些错误。请发布完整的 ViewModel 类并解释如何将 M 传递给 VM 并将 VM 传递给 V,我将再看一遍。

如果执行ClientInfo时为 null,Submit(..)则表示您的 ViewModel 没有模型。ClientInfo您的 ViewModel 上的分配一定有问题。尝试在ClientInfosset 访问器中设置断点,看看是否设置了一次且仅设置一次。例如,尝试在FirstNames set 访问器中设置断点,并查看在 UI 中输入名称时它是否被命中。输出控制台中是否显示任何 BindingErrors?

话虽这么说,你确定你想做你正在尝试的事情吗?如果您创建一个新类,并从另一个类ClientInfo分配属性,则您的两个对象指向完全相同的对象。由于只有这两个属性,我可以想到为什么要复制该对象。您可以很好地使用原始对象,即您的 ViewModel 的模型...ClientClientProfileClientInfoClientInfoClientClientProfileClientInfoClientInfo

其次,您的 ViewModel 直接公开了 Model,这实际上并不是 ViewModel 的重点,尤其是当您最终得到像这样的链式绑定时

Text="{Binding Path=ClientInfo.Client.FirstName}"

ViewModels 的核心能力是聚合数据并允许从 View 轻松绑定。我会在 ViewModel 上公开一个FirstNameLastName等属性,并让 ViewModel 找出从哪里获取数据并将数据推送到哪里。请记住,您希望视图独立于后台的任何实现细节。

也许这两个建议已经解决或完全避免了这个问题。否则,请随时发布更多上下文,我会再看看。

编辑

在您的 ViewModel 中,我期望类似

ClientInfoModel = clientService.GetClientInfo(...);

您注入服务,但您在哪里初始化clientInfoModel

于 2013-05-28T08:04:14.223 回答