【发布时间】:2018-07-21 10:48:59
【问题描述】:
(参见下面的解决方案)
努力学习 MVVMLight 和 WPF。很高兴获得带有 3 个按钮的框架的页面导航,并让 CanExecute RelayCommand 功能适用于这些按钮。
但是,当我使用框架中的“后退”和“前进”按钮更改页面时,框架导航按钮似乎没有提升视图模型中框架源属性 FrameURI 的 propertychanged。在 RelayCommand 执行中,我正在查看 FrameURI 属性以确定可以执行的按钮命令。我在想,在按下 Frame FWD 或 BACK 按钮后,我需要在 viewmodel 中引发 FrameURI 属性的propertychange。看起来我可以在来自NavigationService Class 的 Navigated 或 LoadCompleted EVENT 中做到这一点。这是解决这个问题的最好方法吗?也许有更简单的方法?
此处的正确行为:
当按下框架返回按钮时,此处无法正常工作。页面发生了变化(很好),但是 Middle canexecute 按钮没有正确更新。请参阅下面的属性和中继命令。
MVVMINPCPROPERTY sn-p
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);
}
}
框架的 XAML
<Frame x:Name="MainFrameDS" Source="{Binding FrameUri}" HorizontalAlignment="Left" Height="211" Margin="109,88,0,0" VerticalAlignment="Top" Width="258"/>
RelayCommand 示例
private RelayCommand _changeToLastPage;
/// <summary>
/// Gets the ChangeToLastPage.
/// </summary>
public RelayCommand ChangeToLastPage
{
get
{
return _changeToLastPage
?? (_changeToLastPage = new RelayCommand(
() =>
{
FrameUri = ViewModelLocator.LastPageUri;
},
() => FrameUri != ViewModelLocator.LastPageUri));
}
}
我有source code on github 并使用 Win7 和 VS2017 社区。我还有其他关于程序的问题,并在 github 上打开了问题。任何帮助表示赞赏。
我的目标是拥有一些基本的 MVVMLight 程序“模板”,我可以从中提取并与像我这样的其他学习者分享...谢谢。
解决方案
- 将 Mode=twoway 添加到每个 @steve-teece 的绑定中。
- 对输出窗口进行了一些 DEBUG.writeline(根据@Michael-Randall 提出的断点建议),发现页面的 URI 不同,具体取决于它是引用回 viewmodellocater.IntroPageUri 还是由框架 FWD 调用或返回按钮。
两个 URI 结果是: /IntroPage.xaml 或 IntroPage.xaml
我的假设是“非前斜线”版本不等于带有“/”的版本。
我不确定解决此问题的最佳方法,因此我将 URI 转换为字符串,并将它们与布尔方法中的字符串 Contains 方法进行比较。
我替换了以下行:
FrameUri != ViewModelLocator.IntroPageUri
它被替换为方法调用:
CheckUri(FrameUri, ViewModelLocator.IntroPageUri)
还有,CheckUri 方法:
private Boolean CheckUri(Uri _frameUriToCheck, Uri _vmUri)
{
string StringUriToCheck = _frameUriToCheck.ToString();
string StringUriVM = _vmUri.ToString();
System.Diagnostics.Debug.WriteLine(StringUriToCheck, "StringUriToCheck");
System.Diagnostics.Debug.WriteLine(StringUriVM, "StringUriVM");
if (StringUriVM.Contains(StringUriToCheck))
{ return false; }
else
{ return true; }
}
成功了!如果有人有更好的方法来解决它,我会全力以赴。
感谢大家的反馈!
【问题讨论】:
标签: c# wpf mvvm viewmodel mvvm-light