我们正在使用 MVVMLight 开发 Xamarin Forms (v2.3.0.107)应用程序,主要在XAML中实现。
我们的应用中有几个月LoginView
使用DataTriggers
来显示登录过程中的当前步骤(环境选择 - >凭据 - >验证码)。到目前为止,视图始终是它的一部分,但现在它甚至没有显示任何内容,好像DataTriggers
永远不会被触发。
此视图及其ViewModel上没有直接更改任何内容,大多数间接更改与此问题无关。
LoginView
<ContentPage
x:Class="MyProject.Views.LoginView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:viewmodels="clr-namespace:MyProject.ViewModels;assembly=MyProject"
BindingContext="{Binding [LoginViewModel], Source={StaticResource ViewModelLocator}}">
<Grid>
<StackLayout
IsVisible="False">
<StackLayout.Triggers>
<DataTrigger
TargetType="StackLayout"
Binding="{Binding LoginStatus}"
Value="{x:Static viewmodels:LoginStatus.Login}">
<Setter
Property="IsVisible"
Value="True" />
</DataTrigger>
</StackLayout.Triggers>
...
</StackLayout>
...
</Grid>
</ContentPage>
LoginViewModel
namespace MyProject.ViewModels
{
public enum LoginStatus
{
Login,
EnvironmentSelection,
InstanceSelection,
VerificationCode
}
public class LoginViewModel : BaseViewModel
{
private LoginStatus _loginStatus;
public LoginStatus LoginStatus
{
get { return _loginStatus; }
private set { Set(ref _loginStatus, value); }
}
public LoginViewModel()
{
LoginStatus = LoginStatus.Login;
}
}
}
到目前为止我尝试了什么
我使用以下DebugConverter
来调试绑定:
public class DebugConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Debugger.Break();
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
Debugger.Break();
return value;
}
}
我已将StackLayout DataTrigger的绑定更改为:
Binding="{Binding LoginStatus, Converter={StaticResource DebugConverter}, ConverterParameter={x:Static viewmodels:LoginStatus.Login}}"
这允许我验证从ViewModel收到的任何内容确实是我在DataTrigger中提供的值。实际上,转换器中的value
和parameter
参数都是枚举值MyProject.ViewModels.LoginStatus.Login
。即使我在value == parameter
上快速观察,我也会得到结果。
此外,当我将StackLayout
的{{1}}设置为True时, DOES 会向我显示内容。
这告诉我什么?
IsVisible
的BindingContext绑定到LoginView
。LoginViewModel
并且具有正确的值(无论如何最初都不应该更改)。我在WPF中实现了很多这样的基本触发器,从那时起它就一直在Xamarin中运行。为什么这个实现突然决定失败?我必须检查Setter实现大约10次,但我只是看不到语法中的任何错误。
我错过了什么吗?根据搜索结果,这不是一个常见的问题...
答案 0 :(得分:1)
问题的根源是我自己的愚蠢错误......
我扩展了我们的NavigationService
以允许定义可选的ViewModel,但是我忘了验证手动ViewModel是否为空。因此,在ViewModelLocator
初始化BindingContext
之后,NavigationService
将使用BindingContext
覆盖null
。
我没有注意到这种行为,因为DebugConverter
设置为BindingContext
时未调用null
。相反,它将使使用BindingContext
的任何触发器无效并还原任何被调用的Setter。