我正在努力获得Laurent Bugnion在他的一些视频中谈论的精彩设计时间体验。这是Win7机器上VS2017社区中的WPF应用程序。
在窗口中,FRAME控件绑定到URI。 Source =“{Binding FrameUri,Mode = TwoWay}”程序在运行时工作,但在设计时,我有以下链接到框架中显示的URL(见第一张图片)。
值得注意的是,MainPage有MainViewModel,IntroPage也有自己的viewmodel(IntroViewModel)。
RUNTIME IMAGE
我猜测Intro页面在设计时没有实例化,但不知道如何做。我试图在Frame xaml中添加一个设计时间线,但这不起作用:d:DataContext =“{d:DesignInstance viewModels:PageViewModel,IsDesignTimeCreatable = True}”
我也尝试在XAML中添加Path = IntroPageViewModel,但这也不起作用。
我在这里有代码:https://github.com/floppydisk525/MvvmLight_WPF_Frame_Nav/tree/NavTest
这是代码:
APP.XAML文件
<Application.Resources>
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
<DataTemplate DataType="{x:Type vm:IntroViewModel}">
<v:IntroPage/>
</DataTemplate>
</Application.Resources>
</Application>
FRAME代码:
<Frame x:Name="MainFrameDS" Source="{Binding FrameUri, Mode=TwoWay}" HorizontalAlignment="Left" Height="211" Margin="109,88,0,0" VerticalAlignment="Top" Width="258"/>
FRAME URI PROPERTY:
public const string FrameUriPropertyName = "FrameUri";
private Uri _frameUri;
/// <summary>
/// Sets and gets the FrameUri property.
/// Changes to that property's value raise the PropertyChanged event.
/// </summary>
public Uri FrameUri
{
get
{
return _frameUri;
}
set
{
Set(FrameUriPropertyName, ref _frameUri, value);
System.Diagnostics.Debug.WriteLine(_frameUri.ToString(), "_frameUri");
System.Diagnostics.Debug.WriteLine(FrameUri.ToString(), "FrameUri");
}
}
FROM ViewModelLocator
public class ViewModelLocator
{
public static readonly Uri IntroPageUri = new Uri("/IntroPage.xaml", UriKind.Relative);
public static readonly Uri MiddlePageUri = new Uri("/MiddlePage.xaml", UriKind.Relative);
public static readonly Uri LastPageUri = new Uri("/LastPage.xaml", UriKind.Relative);
static ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
var NavigationService = new NavigationService();
SimpleIoc.Default.Register<INavigationService, NavigationService>();
SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<IntroViewModel>();
SimpleIoc.Default.Register<MiddleViewModel>();
SimpleIoc.Default.Register<LastViewModel>();
`#if DEBUG
if (ViewModelBase.IsInDesignModeStatic)
{
var instance = SimpleIoc.Default.GetInstance<IntroViewModel>();
}
`#endif
}
答案 0 :(得分:1)
我猜测在设计过程中没有实例化Intro Page 时间,但不知道该怎么做。我试着添加一个设计时间线 Frame xaml,但是没有用:d:DataContext =&#34; {d:DesignInstance viewModels:PageViewModel,IsDesignTimeCreatable = True}&#34;
单独的xaml部分是不够的。 要在设计时实例化视图模型,您应该在ViewModelLocator中使用&#34; ViewModelBase.IsInDesignModeStatic&#34; 。
if (ViewModelBase.IsInDesignModeStatic)
{
SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
}
else
{
SimpleIoc.Default.Register<IDataService, DataService>();
}
如果您需要更多信息,This似乎是一篇不错的文章。
答案 1 :(得分:0)
我偶然发现了一个解决方案,尽管有一个新问题。
我正在尝试不同的事情,最近一次来自stackoverflow example。我在github MvvmLight_Frame_DesignTime上有一个工作解决方案,有更详细的写作和图片。
首先在MainWindow.xaml文件中添加以下行。
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:ignore="http://www.galasoft.ch/ignore"
xmlns:v="clr-namespace:MvvmLight_Frame_DesignTime"
然后,Frame控件将d:designtime代码与Content Property一起添加。
<Frame HorizontalAlignment="Left" Height="237" Margin="25,120,0,0" VerticalAlignment="Top" Width="243"
d:DataContext="{d:DesignInstance Type=v:IntroPage, IsDesignTimeCreatable=True}"
Content ="{Binding}"
Source="{Binding FrameUri}"/>
需要注意的重要一点是,我没有从Viewmodel代码或代码后面的代码实例化Frame或Page控件,就像上面的堆栈溢出示例一样。这使得解决方案非常简单且代码很少。
可以使用Source&amp;框架的内容属性?可以这样做吗?
我认为它的工作方式是在设计模式下,DesignInstance使用Type = v:IntroPage进行实例化,并绑定到Content属性。在运行时期间,由于未创建IntroPage类型且MainViewModel FrameUri属性绑定到Frame Source,因此优先。似乎工作,不知道它可能产生什么问题。