问候!我喜欢使用MVVM轻巧的框架 - 让我的生活变得更加轻松,并且已经消除了许多难以克服的障碍......
题:
我正在尝试设置一个自定义对话框,用于编辑用户相互发送的消息.我正在尝试使用MVVM框架使用ChildWindow对象构造一个Silverlight自定义对话框.
想知道是否有任何关于如何实现这一点的建议
在我找到的对话框MVVM示例代码之后:http://mvvmlight.codeplex.com/Thread/View.aspx?ThreadId = 209338我被卡住了,因为Silverlight中的ChildWindow对话框对象是异步的,并且具有不同的Result类.
所以 - 我现在的基本思想是使用类的视图模型(在本例中为Matrix.MessageViewModel)来创建自定义对话框的实例,通过Messenger.Send <>发送它,处理已注册的消息显示对话框的视图,然后让ChildWindow对话框的Save按钮处理程序触发Messenger.Send,修改后的内容然后使用viewmodel上的Save方法存储...
看起来有点圆 - 所以想确保没有更清洁的方式....
相关代码位:
查看模型:
messageDialogBox = new MessageEditorDialog(
selectedMessage, this.SelectedSiteId, this.LoggedOnEmployee.Id, this.Projects);
DialogMessage editMessage = new DialogMessage(
this, messageDialogBox,"Edit Message", DialogMessageCallback);
Messenger.Default.Send(editMessage);
Run Code Online (Sandbox Code Playgroud)
视图:
public ViewHost()
{
InitializeComponent();
Loaded += new RoutedEventHandler(ViewHost_Loaded);
if (!ViewModelBase.IsInDesignModeStatic)
{
// Use MEF To load the View Model
CompositionInitializer.SatisfyImports(this);
}
ApplicationMessages.IsBusyMessage.Register(this, OnIsBusyChange);
Messenger.Default.Register<DialogMessage>(this, msg => ShowDialog(msg));
}
private void ShowDialog(DialogMessage msg)
{
MessageEditorDialog myDialog = (MessageEditorDialog) msg.Target;
myDialog.Show();
}
Run Code Online (Sandbox Code Playgroud)
对话保存: …
我试图找出一种方法让我的ViewModel处理页面导航时从或从中保存或恢复页面的状态.
我尝试的第一件事是向页面添加EventToCommand行为,但事件(OnNavigatedFrom和OnNavigatedTo)被声明为受保护,并且EventToCommand没有看到要绑定的事件.
接下来我想我会尝试使用Messenger类使用View后面代码中的代码将消息传递给ViewModel:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this);
base.OnNavigatedTo(e);
}
Run Code Online (Sandbox Code Playgroud)
但这似乎有两个问题,首先是在代码隐藏页面中使用此代码.其次,ViewModel无法区分OnNavigatedFrom和OnNavigatedTo事件,而无需为PhoneApplicationPage对象创建一个包装类(请参阅下面的更新).
什么是MVVM-Light最友好的方式来处理这些事件?
更新:我能够通过发送这样的消息来解决第二个问题:
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this,"NavigatedFrom");
base.OnNavigatedFrom(e);
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
Messenger.Default.Send<PhoneApplicationPage>(this, "NavigatedTo");
base.OnNavigatedTo(e);
}
Run Code Online (Sandbox Code Playgroud)
并像这样注册它们:
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedFrom", false, (action) => SaveState(action));
Messenger.Default.Register<PhoneApplicationPage>(this, "NavigatedTo", false, (action) => RestoreState(action));
Run Code Online (Sandbox Code Playgroud) 我试图在Silverlight 4中编写可测试的ViewModel.我正在使用MVVM灯.
我正在使用AutoFac和IoCContainer正在完成它的工作.但是要注入ViewModel的构造函数,它绑定到Views我有这个构造函数链接:
public UserViewModel() : this(IoCContainer.Resolve<IUserServiceAsync>())
{
}
public UserViewModel(IUserServiceAsync userService)
{
if (this.IsInDesignMode) return;
_userService = userService;
}
Run Code Online (Sandbox Code Playgroud)
哪个不干净,但是到目前为止我找到的最佳选择.这是有效的,我的应用程序可以根据需要工作,并且可以通过控制倒置来测试
但是,我的VM绑定到我的视图,如下所示:
<UserControl.DataContext>
<ViewModel:UserViewModel />
</UserControl.DataContext>
Run Code Online (Sandbox Code Playgroud)
在我的XAML页面属性中,VS2010和Blend中的设计模式都不起作用.
是否有更好的方法来实现我在Silverlight中尝试仍然适用于设计模式的东西?丢失设计模式不是一个交易破坏者,但在学习XAML时会很方便.一个更干净的无链接方式会很好!
我认为可以使用AutoFac/IoC将视图模型解析为视图,与上面的XAML标记方法一致,并沿着这条路线走下去?
谢谢.
我在我当前的Windows Phone项目中使用SterlingDB,我希望能够使用MVVM Light v4中的新SimpleIoC容器从我的应用程序中的各个位置解析Sterling数据库.
但是,我不确定SimpleIoC是否支持注册单例.SterlingDB引擎只应在应用程序首次启动时创建,并且我不希望每次容器注入对它的引用时都会启动新实例.
如果我有不同的方式来思考这个问题,我也很乐意接受替代方案.
我正在使用Nuget(4.1.23.0)上可用的当前版本的MvvmLight,并且调用RaiseCanExecuteChanged似乎在单元测试中没有做任何事情.场景非常简单,我有一个命令:
public RelayCommand FooCommand { get; private set; }
Run Code Online (Sandbox Code Playgroud)
我在视图模型构造函数中新建它并将其指向一些私有方法:
FooCommand = new RelayCommand(Foo, CanFoo);
private void Foo()
{
// do some fooing.
}
private bool CanFoo()
{
return SomeRequiredProperty != null;
}
Run Code Online (Sandbox Code Playgroud)
然后在setter中SomeRequiredProperty我调用RaiseCanExecuteChanged:
public object SomeRequiredProperty
{
get
{
return someRequiredProperty;
}
set
{
someRequiredProperty = value;
FooCommand.RaiseCanExecuteChanged();
}
}
Run Code Online (Sandbox Code Playgroud)
现在在单元测试中,我执行以下操作:
// Arrange
var canExecuteChanged = false;
viewModel.FooCommand.CanExecuteChanged += (sender, args) => canExecuteChanged = true;
// Act
viewModel.SomeRequiredProperty = new object();
// Assert
Assert.That(canExecuteChanged, Is.True);
Run Code Online (Sandbox Code Playgroud)
测试失败,因为我的事件处理程序没有触发.这是为什么?
更新: …
我使用GalaSoft的RelayCommand遇到了一些问题.
我有一个可以工作的NextCommand属性,但只有几次.
之后,它完全停止工作.
您可以使用示例项目尝试此操作:
http://s000.tinyupload.com/?file_id=65828891881629261404
行为如下:
复制步骤:
所需的重复次数(复制错误)是不一致的.
有时我会在重复4次后得到它; 其他时间到9.

// Items Collection
public class ItemCollection : ViewModelBase
{
// List of Items
private readonly ObservableCollection<Item> _items = new ObservableCollection<Item>();
public ObservableCollection<Item> Items
{
get { return _items; }
}
// Constructor
public ItemCollection()
{
BackCommand = new RelayCommand(
() =>
{
// Go to previous page
var index = Items.IndexOf(ActiveItem); …Run Code Online (Sandbox Code Playgroud) 使用Messenger课程的正确方法是什么?我知道它可以用于ViewModels/Views通信,但它是一个很好的方法用于技术/业务服务层吗?
例如,日志记录/导航服务在构造函数中注册某些消息,并且知道应用程序中何时出现这些消息.发件人(ViewModel ou Service)不引用服务接口,而只引用发送消息的信使.这是一个示例服务:
using System;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using App.Service.Interfaces;
using GalaSoft.MvvmLight.Messaging;
namespace App.Service
{
public class NavigationService : INavigationService
{
private PhoneApplicationFrame _mainFrame;
public event NavigatingCancelEventHandler Navigating;
public NavigationService()
{
Messenger.Default.Register<NotificationMessage<Uri>>(this, m => { this.NavigateTo(m.Content); });
}
public void NavigateTo(Uri pageUri)
{
if (EnsureMainFrame())
{
_mainFrame.Navigate(pageUri);
}
}
public void GoBack()
{
if (EnsureMainFrame()
&& _mainFrame.CanGoBack)
{
_mainFrame.GoBack();
}
}
private bool EnsureMainFrame()
{
if (_mainFrame != null)
{
return true;
}
_mainFrame …Run Code Online (Sandbox Code Playgroud) 我正在学习使用MVVM Light的WPF,我的可移植类库存在问题.我遵循这个教程:http://www.codeproject.com/Articles/536494/Portable-MVVM-Light-Move-Your-View-Models
我参考MVVM Light创建了一个门户类库和一个WPF mvvm light 4.5.我在我的wpf项目中添加了我的PCL的引用.所以在我的PCL中,我添加了一个文件夹ModelView并在我的ModelViewLocator中
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc;
using Microsoft.Practices.ServiceLocation;
using EasyDevis.EasyDevisPCL.Model;
using EasyDevis.EasyDevisPCL.ViewModel.MainPage;
namespace EasyDevis.EasyDevisPCL.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class ViewModelLocator
{
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<MainPageViewModel>();
}
/// <summary>
/// Gets the Main property.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
"CA1822:MarkMembersAsStatic", …Run Code Online (Sandbox Code Playgroud) 应该是一个简单的答案,但我没有看到它.
MVVM Light v5引入了NavigationService和DialogService.我想制作一个示例应用程序来玩它们.建议似乎是我需要做的就是注册它们ViewModelLocator:
SimpleIoc.Default.Register<IDialogService, DialogService>();
在IDialogService需要Galasoft.MvvmLight.Views空间,它就会自动解决,但DialogService类不能被发现,并且VS不能推荐一个命名空间导入.
类似的 NavigationService
更新
上传的示例项目:https://github.com/subt13/BugSamples
我已经重现了在使用MVVMLight框架的Windows 10 UAP应用程序中发生的错误.
在CPU处于高负载(~20-25%)且页面"重"(大图像,大量控件等等)时,我在导航期间收到以下错误
at System.Runtime.InteropServices.WindowsRuntime.ICommandAdapterHelpers.<> c__DisplayClass2.b__3(Object sender,EventArgs e),位于RaiseExecuteChangeRepo的GalaSoft.MvvmLight.Command.RelayCommand.RaiseCanExecuteChanged()的System.EventHandler.Invoke(Object sender,EventArgs e) .ViewModel.MainViewModel.d__17.MoveNext()
在示例中,发生错误 RaiseCanExecuteChanged();
private async void ExecuteLoadDataCommandAsync()
{
// cause the app to slow done.
var data = await Task.Run(() => GetData());
if (data != null)
{
this.Data.Clear();
foreach (var item in data)
{
this.Data.Add(new AnotherVM(item));
}
}
// have the select job command rerun its condition
this.SelectCommand.RaiseCanExecuteChanged();
}
// slow down the page
public List<DataItem> GetData()
{
var myList = new List<DataItem>();
for …Run Code Online (Sandbox Code Playgroud) mvvm-light ×10
c# ×5
wpf ×4
mvvm ×2
relaycommand ×2
silverlight ×2
async-await ×1
childwindow ×1
messaging ×1