我正在尝试学习WPF和MVVM问题,但是遇到了障碍.这个问题与此问题相似但不完全相同(处理对话框-wpf-with-mvvm) ...
我有一个使用MVVM模式编写的"登录"表单.
此表单有一个ViewModel,它包含用户名和密码,这些用户名和密码使用普通数据绑定绑定到XAML中的视图.它还有一个"登录"命令,该命令绑定到表单上的"登录"按钮,使用正常数据绑定.
当"登录"命令触发时,它会调用ViewModel中的一个函数,该函数将关闭并通过网络发送数据以进行登录.当此函数完成时,有2个操作:
登录无效 - 我们只显示一个MessageBox,一切都很好
登录有效,我们需要关闭登录表单并让它返回true作为其DialogResult...
问题是,ViewModel对实际视图一无所知,那么如何关闭视图并告诉它返回一个特定的DialogResult?我可以在CodeBehind中粘贴一些代码,和/或将View传递给ViewModel,但这似乎完全打败了MVVM的全部内容......
最后,我刚刚违反了MVVM模式的"纯度",并让View发布了一个Closed事件,并公开了一个Close方法.ViewModel然后才会调用view.Close.该视图仅通过接口已知并通过IOC容器连接,因此不会丢失可测试性或可维护性.
接受的答案是-5票,这似乎很愚蠢!虽然我很清楚通过在"纯粹"时解决问题所获得的良好感受,当然我不是唯一一个认为200行事件,命令和行为只是为了避免单行方法"模式"和"纯度"的名称有点荒谬......
我最近遇到了为我的wpf应用程序创建添加和编辑对话框的问题.
我想在代码中做的就是这样.(我主要使用viewmodel第一种方法与mvvm)
调用对话框窗口的ViewModel:
var result = this.uiDialogService.ShowDialog("Dialogwindow Title", dialogwindowVM);
// Do anything with the dialog result
Run Code Online (Sandbox Code Playgroud)
它是如何工作的?
首先,我创建了一个对话服务:
public interface IUIWindowDialogService
{
bool? ShowDialog(string title, object datacontext);
}
public class WpfUIWindowDialogService : IUIWindowDialogService
{
public bool? ShowDialog(string title, object datacontext)
{
var win = new WindowDialog();
win.Title = title;
win.DataContext = datacontext;
return win.ShowDialog();
}
}
Run Code Online (Sandbox Code Playgroud)
WindowDialog是一个特殊而简单的窗口.我需要它来保留我的内容:
<Window x:Class="WindowDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="WindowDialog"
WindowStyle="SingleBorderWindow"
WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight">
<ContentPresenter x:Name="DialogPresenter" Content="{Binding .}">
</ContentPresenter>
</Window>
Run Code Online (Sandbox Code Playgroud)
wpf中对话框的问题是dialogresult = true只能在代码中实现.这就是为什么我为我dialogviewmodel实现它的界面.
public class …Run Code Online (Sandbox Code Playgroud) 点击后,我Button关闭了我的窗口:
<Button x:Name="buttonOk" IsCancel="True">Ok</Button>
Run Code Online (Sandbox Code Playgroud)
这很好,直到我添加Command到Buttonie
<Button x:Name="buttonOk"
Command="{Binding SaveCommand}"
IsCancel="True">Ok</Button>
Run Code Online (Sandbox Code Playgroud)
现在它不会因为我正在处理它而关闭Command.我可以通过EventHandler输入和调用this.Close()ie 来解决这个问题
<Button x:Name="buttonOk"
Click="closeWindow"
Command="{Binding SaveCommand}"
IsCancel="True">Ok</Button>
Run Code Online (Sandbox Code Playgroud)
但现在我的代码背后有代码,即方法SaveCommand.我使用的是MVVM模式,SaveCommand是我代码中唯一的代码.
我怎么能以不同的方式做到这一点,以免背后使用代码?
好的,我真的想知道专家MVVM开发人员如何处理WPF中的openfile对话框.
我真的不想在我的ViewModel中执行此操作(其中'Browse'通过DelegateCommand引用)
void Browse(object param)
{
//Add code here
OpenFileDialog d = new OpenFileDialog();
if (d.ShowDialog() == true)
{
//Do stuff
}
}
Run Code Online (Sandbox Code Playgroud)
因为我认为这违背了MVVM方法论.
我该怎么办?
我的视图模型类有一个连接到服务的方法(不确定这是好的做法,还是视图模型应该是严格的属性和属性更改机制).当然,我想在连接或断开连接时处理任何可能的WCF异常.
让我们使用未找到的端点作为示例,考虑到这是一个我希望引起用户注意的异常.考虑粗略的代码示例:
public void Connect()
{
ServiceClient proxy = null;
try
{
proxy = new ServiceClient();
proxy.Subscribe();
// ...
}
catch(EndpointNotFoundException)
{
// should I do something here?
}
// .. other WCF related exception catches and a finally
}
Run Code Online (Sandbox Code Playgroud)
是否可以直接在catch中调用System.Windows.MessageBox.Show()或者我是否应该重新抛出异常以便我的WPF应用程序的另一层捕获它?如果是这样,那么捕捉这种例外的理想地点在哪里?
在MVVM WPF应用程序中.
你如何设置第二个Windows父级ViewModel?
例:
view1 - viewModel1
viewModel1的命令调用:
var view2 = new view2
Run Code Online (Sandbox Code Playgroud)
view2.Owner= <----这是问题所在.如何从这里获取view1作为所有者viewModel?
view2.Show()
Run Code Online (Sandbox Code Playgroud)
编辑:
请参阅下面接受的答案,然后阅读以下编辑内容.
我正在使用MVVM灯 - > http://mvvmlight.codeplex.com/ (真棒顺便说一句)
烘焙消息传递系统非常棒.我现在正在从viewmodel向我的视图发送一条消息,告诉它显示另一个窗口.
对于消息我当前在主视图中使用带有switch语句的字符串来确定要打开的视图; 但是我可能会修改也是MVVM light toolkit一部分的令牌.
谢谢!
我想在我的MVVM WPF应用程序中显示消息框.所以从哪里调用MessageBox.Show().
我有一个应用程序,需要从用户输入一些信息的按钮打开一个对话框.
目前我这样做(工作正常)
有很多步骤,但它们都有意义,并没有太多的打字.
代码看起来像这样(窗口要求输入用户名)
视图模型:
AskUserNameCommand = DelegateCommand(AskUserNameExecute);
...
public event EventHandler<AskUserEventArgs> AskUserName;
void AskUserNameExecute(object arg) {
var e = new AskUserNameEventArgs();
AskUserName(this, e);
mModel.SetUserName(e.UserName);
}
Run Code Online (Sandbox Code Playgroud)
控制器:
mViewModel.AskUserName += (sender,e) => {
var view = container.Resolve<IAskUserNameView>();
var model = container.Resolve<IAskUserNameModel>();
var viewmodel = container.Resolve<IAskUserNameViewModel>(view, model);
if (dlg.ShowDialog() ?? false)
e.UserName = model.UserName;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是水平通信如何在MVVM模式中工作.不知何故,让控制器参与模型之间的数据传输似乎是错误的.
我已经查看了中介模式,让模型直接进行通信.不喜欢这个想法,因为它使模型取决于GUI的实现细节.(即如果用文本框替换对话框,模型需要更改)
在弹出窗口方面,我对VM的职责有疑问.当应用程序弹出消息框或某种对话框(使用MVVM)时,我们拥有的两个选项是:
你们是怎么解决这个案子的?
我创建了一个窗口,其中包含一个ListView显示人员集合的窗口.还有3个TextBoxes应该显示人的名字和姓氏,以及年龄.最后,有一个Button保存在这些TextBoxes中输入的新人数据.
ListView通过实现MVVM来加载人员.奇迹般有效!此外,通过单击Button也可以通过MVVM 将新人添加到集合中.
但是有两个用例,我不确定使用命令是更明智的,即MVVM,还是简单的代码隐藏.用例是:
ListView,TextBoxes应显示人员详细信息.TextBox显示人的年龄的数字时,应警告他或她输入的数据不正确.我怀疑是否应该使用MVVM或代码隐藏的原因是因为两个用例都与仅视图(GUI)相关,即与模型或应用程序业务逻辑没有交互性.该ListView项目源绑定到人的集合ObservableColleciton<Person>,并与被选择的人的所有数据已经传递到当视图ListView中填充的物品.在第二个用例中,再次,没有必要转到ViewModel,以便让它触发有关错误用户输入的消息框.如何在ViewModel类的age依赖属性中创建验证回调呢?
感谢您的所有澄清.
我尝试使用MVVM模式重写我的应用程序.
我有一个窗口,用静态方法显示不同对象的相关文档,如下所示:
public partial class ShowRelatedDocuments : Window
{
private ShowRelatedDocuments()
{
InitializeComponent();
}
public static void ShowRelatedDocument(A objA)
{
ShowRelatedDocuments srd = new ShowRelatedDocuments();
srd.HandleA(objA);
srd.ShowDialog();
}
public static void ShowRelatedDocument(B objB)
{
ShowRelatedDocuments srd = new ShowRelatedDocuments();
srd.HandleB(objB);
srd.ShowDialog();
}}
Run Code Online (Sandbox Code Playgroud)
有没有办法让这些方法像这样保持静态?
ShowRelatedDocumentsVM.ShowRelatedDocument(A objA);
ShowRelatedDocumentsVM.ShowRelatedDocument(B objB);
Run Code Online (Sandbox Code Playgroud)
我没有找到任何有关ViewModels和静态方法的信息.VM可以创建自己的实例并显示他的View(这里是一个窗口)吗?
或者是将对象作为参数传递给VM的构造函数的更好方法吗?
public ShowRelatedDocumentsVM(A objA)
{
HandleA(obj A)
ShowRelatedDocuments srd = new ShowRelatedDocuments();
srd.DataContext = this;
srd.ShowDialog();
}
public ShowRelatedDocumentsVM(B objB)
{
HandleB(objB);
ShowRelatedDocuments srd = new ShowRelatedDocuments();
srd.DataContext = this;
srd.ShowDialog();
} …Run Code Online (Sandbox Code Playgroud) 我正在构建一个WPF应用程序并尝试符合MVVM最佳实践.我正在使用MVVM Foundation框架,并注意到我读过的Messenger类应该用于处理WPF中的对话框.这听起来很棒,但我完全不了解如何使用Messenger来实现此目的.从字面上看,我想要做的就是打开一个模态关于对话框 - 我不需要来回传递任何消息.
Messenger类的目的是用于对话框需要来自其父级的消息,还是将消息返回给其父级的情况?关于对话框是否有点过分?如果只是将代码添加到事件处理程序以显示对话框,我会更好吗?
wpf ×12
mvvm ×11
c# ×5
.net ×3
dialog ×2
code-behind ×1
messenger ×1
modal-dialog ×1
mvvm-light ×1
popup ×1
static ×1
xaml ×1