让Silverlight MVVM使用Expression Blend设计时数据?

时间:2010-07-28 18:06:24

标签: silverlight mvvm silverlight-4.0

我是Silverlight的MVVM模式的大力支持者。目前,我通过在视图后面的代码中查看ViewModel将ViewModel连接到View,因此:

public partial class SomePage : UserControl
{
    public SomePage()
    {
        InitializeComponent();

        // New up a ViewModel and bind to layout root
        var vm = new SomeViewModel();
        LayoutRoot.DataContext = vm;
    }
}

然后所有绑定都在View中处理,并且所有逻辑都在ViewModel中处理,就像模式一样。

但是,以这种方式连接它们意味着设计器不能很好地工作,我不能使用Expression Blend设计时数据。我知道有一些像MVVM Light这样的库可以帮助实现这一切,但我不想引入一个库,因为这是“还有一件事”需要处理。

是否有一个简单的模式可以让MVVM在Silverlight中连接,同时保持设计器功能,特别是在Blend中?我已经完成了一些谷歌搜索,但是有太多过时的文章和WPF和Silverlight以及旧版本之间的混淆,我很难搞清楚要使用哪些。

BTW如果重要的话,我会专注于使用VS2010的SL4。

3 个答案:

答案 0 :(得分:3)

您可以使用一些方法。

首先,让Expression的Sample Data和设计时属性(即d:DataContext)接管设计器。在您的代码中,您只需调整视图模型绑定:

if (!DesignerProperties.IsInDesignTool)
{
   var vm = new SomeViewModel();
   LayoutRoot.DataContext = vm; 
}

第二,您可以使用特殊的设计时视图模型进行绑定:

LayoutRoot.DataContext = DesignerProperties.IsInDesignTool ?
    new DesignViewModel() : new MyViewModel(); 

最后,另一种方法是管理视图模型中的数据。我不喜欢这样,因为它在所有视图模型中分散了责任,但你有更高的精确度:

// constructor
private Widget[] _designData = new[] { new Widget("Test One"), new Widget("Test Two") };

public MyViewModel()
{
   if (DesignerProperties.IsInDesignTool)
   {
       MyCollection = new ObservableCollection<Widget>(_designData);       
   }
   else 
   {
       MyService.Completed += MyServiceCompleted;
       MyService.RequestWidgets();
   }
}

private void MyServiceCompleted(object sender, AsynchronousEventArgs ae)
{
   // load up the collection here
}

希望有所帮助!

答案 1 :(得分:2)

您要找的是“ Blendibility ”。 MVVM Light有一个ViewModelLocator的概念,我在一个项目中使用它,效果很好。

这是Roboblob关于该主题的精彩帖子。 http://blog.roboblob.com/2010/01/17/wiring-up-view-and-viewmodel-in-mvvm-and-silverlight-4-blendability-included/这篇文章有一个示例解决方案,所以它真的有助于理解。 Rob改进了MVVM Light的实现,我认为做得很好。

答案 2 :(得分:1)

我遇到了设计WPF应用程序的类似问题。我学到的一个技巧是声明一个xmlns,这样你就可以在XAML中嵌入一个对象数组:

xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib"

然后,您可以将几乎任何内容的ArrayList放入XAML:

<coll:ArrayList x:Key="questions">
    <local:QuestionItem Title="FOO"></local:QuestionItem>
</coll:ArrayList>

然后,您可以将网格,列表框等的ItemsSource设置为数组:

<ListBox x:Name="lstStuff" ItemsSource="{StaticResource questions}" />

此技术允许您“预览”设计器中列表样式控件的外观。它并没有解决视觉原型设计的所有问题,但它有很长的路要走,可以适应几种不同的场景。

例如,您可以将本地名称空间声明为xmlns,然后将ViewModel的模拟删除到窗口或控件的Resources中。我没试过这个,但理论上你可以得到一个完整的设计时预览。