DataTrigger中的Setter似乎没有触发

时间:2016-07-07 07:23:31

标签: c# xaml xamarin xamarin.forms

我们正在使用 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中提供的值。实际上,转换器中的valueparameter参数都是枚举值MyProject.ViewModels.LoginStatus.Login。即使我在value == parameter上快速观察,我也会得到结果。

此外,当我将StackLayout的{​​{1}}设置为True时, DOES 会向我显示内容。

这告诉我什么?

  • 我的IsVisible的BindingContext绑定到LoginView
  • 我的DataTrigger的绑定确实绑定到LoginViewModel并且具有正确的值(无论如何最初都不应该更改)。
  • 我的DataTrigger中的值也会返回正确的值。
  • DataTrigger的条件有效,因此Setter应该触发。

我在WPF中实现了很多这样的基本触发器,从那时起它就一直在Xamarin中运行。为什么这个实现突然决定失败?我必须检查Setter实现大约10次,但我只是看不到语法中的任何错误。

我错过了什么吗?根据搜索结果,这不是一个常见的问题...

1 个答案:

答案 0 :(得分:1)

问题的根源是我自己的愚蠢错误......

我扩展了我们的NavigationService以允许定义可选的ViewModel,但是我忘了验证手动ViewModel是否为空。因此,在ViewModelLocator初始化BindingContext之后,NavigationService将使用BindingContext覆盖null

我没有注意到这种行为,因为DebugConverter设置为BindingContext时未调用null。相反,它将使使用BindingContext的任何触发器无效并还原任何被调用的Setter。