WPF MVVM 模式 实现异步登录, 我的做法合理么?

Pc498471249 2014-01-24 03:10:18
场景: 用户登录
我的做法,View层文本框和按钮都绑定ViewModel里对应的Property和Command , 在触发Command之后,我开了一个线程用来处理登录的操作,失败就弹出MessboxShow,成功的话就打开主窗体界面,然后问题来了,我应该在ViewModel层的登录方法里写MainWindow m = new MainWindow();m.Show() ???? (假设主窗体叫MainWindow) , MVVM的思想是UI和逻辑分离, ViewModel不应该出现依赖于View的代码, 也就是说,VM层不应该有一切UI元素的存在,不然就违背了MVVM的初衷。 这里我就纠结了。 我需要在登录成功之后,打开主窗体,应该怎么办呢, 几番思考之后我决定使用Action委托, 在View层声明一个静态的LoginAction,执行要要做的事(打开主窗体), 然后在ViewModel中处理登录成功之后,调用LoginAction ,功能算是实现了。 不过我这样的做法合理吗? 还有没有更好的解决方案。

ViewModel代码:

private void InitCommand()
{
LoginCommand = new DelegateCommand() { ExecuteAction = Login };
}

private void Login(object param)
{
if (!string.IsNullOrEmpty(CustomerId) && !string.IsNullOrEmpty(CustomerName) && !string.IsNullOrEmpty(Password))
{
thread = new Thread(new ThreadStart(UserLogin));
thread.Start();
}
else
{
IsShow_Login = Visibility.Visible;
Error_Login = Enums.Error_Null;
}
}

private void UserLogin()
{
string url = string.Format("{0}DataHandler.ashx?PageType={1}&CustomerId={2}&CustomerName={3}&Password={4}", ApplicationHelper.WebServicePath, (int)Enums.PageType.登录, CustomerId, CustomerName, Password);
Button_Content = "登录中...";

string jsonStr = Tools.GetHttpData(url, (msg) =>
{
Error_Login = msg;
IsShow_Login = Visibility.Visible;
Button_Content = "登录";
});
if (jsonStr != Enums.Error_Http)
{
if (jsonStr != Enums.Error_Login)
{
ApplicationHelper.c = JsonConvert.DeserializeObject<Model_Customer>(jsonStr);
/***判断密码保存***/
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("IsChecked").Value = IsChecked.ToString();
if (IsChecked)
{
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerId").Value = ApplicationHelper.eh.Encrypto(CustomerId);
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerName").Value = ApplicationHelper.eh.Encrypto(CustomerName);
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("Password").Value = ApplicationHelper.eh.Encrypto(Password);
}
else
{
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerId").Value = string.Empty;
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerName").Value = string.Empty;
ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("Password").Value = string.Empty;
}
ApplicationHelper.UserXml.Save(string.Format("{0}\\{1}", AppDomain.CurrentDomain.BaseDirectory, "Xml\\UserConfig.xml"));

/******大神看这里,调用委托打开窗体,我做的对吗?******/
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, LoginWindow.Callback_OpenMainWindow);
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, LoginWindow.Callback_Close);
}
else
{
Button_Content = "登录";
Error_Login = Enums.Error_Login;
IsShow_Login = Visibility.Visible;
}
}
thread.Abort();
}


View层的委托代码

public static Action Callback_Close { get; set; }

public static Action Callback_OpenMainWindow { get; set; }

public LoginWindow()
{
InitializeComponent();
this.DataContext = new LoginWindowViewModel();
btn_Close.Callback_Close = () =>
{
this.Close();
};

btn_Close.Callback_Min = () =>
{
this.WindowState = WindowState.Minimized;
};

Callback_Close = () => { this.Close(); };

Callback_OpenMainWindow = () =>
{
MainWindow mw = new MainWindow();
mw.Show();
};
}


请MVVM大神指点一二
...全文
429 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Pc498471249 2014-02-07
  • 打赏
  • 举报
回复
我利用mvvmlight中的消息机制解决了。 在View层Register一个消息, 在VM层Send, View层的消息对象接受到消息之后open new window, 关闭登录窗体时Unregister。 我没有依赖View, 因为vm层的消息 并不知道谁注册了, 只要注册过的地方, 在vm Send之后都会响应,使用消息机制来处理View和VM的逻辑通信很方便, 还有其他解决方式吗?
Pc498471249 2014-02-07
  • 打赏
  • 举报
回复
引用 7 楼 sp1234 的回复:
你自己口口生生说VM层不纠结UI控件,可是你写出了一堆类似 ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerId"). 这样的垃圾代码,怎么解释? 这样一堆代码,你彻底是说了谎话。
这个只是我定义的全局处理类, 没有涉及到UI控件啊, Xml算UI控件?
yangxk120 2014-02-07
  • 打赏
  • 举报
回复
通过消息机制可以实现这种登录
  • 打赏
  • 举报
回复
你自己口口生生说VM层不纠结UI控件,可是你写出了一堆类似 ApplicationHelper.UserXml.Element("root").Element("UserAccount").Element("CustomerId"). 这样的垃圾代码,怎么解释? 这样一堆代码,你彻底是说了谎话。
  • 打赏
  • 举报
回复
ViewModel绝不涉及UI控件。
  • 打赏
  • 举报
回复
弄个iservice 两个具体实现,一个写代码给测试用,一个实际处理窗体,对话框说明的。 vm中调用iservice某具体实例。
WalkOnly 2014-01-27
  • 打赏
  • 举报
回复
View和ViewModel的区别在哪儿?你要搞清楚吧,这不是XMAL界面和C#界面的区别。所以你这个应该没有问题。。。
Pc498471249 2014-01-25
  • 打赏
  • 举报
回复
没有人遇到过这个问题吗?
pengcong002 2014-01-24
  • 打赏
  • 举报
回复
去看看吧 stackoverflow有讨论

8,734

社区成员

发帖
与我相关
我的任务
社区描述
WPF/Silverlight相关讨论
社区管理员
  • WPF/Silverlight社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧