UWP 窗口 10 可见性绑定到全局变量



我正在尝试将控件的可见性绑定到全局变量:

我有一个可见性转换器:

public class BooleanToVisibilityConverter : IValueConverter
{
    public bool IsReversed { get; set; }
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        return (value is bool && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
    }
    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value is Visibility && (Visibility)value == Visibility.Visible;
    }
}

我还创建了一个继承自 DependencyObject 的类:

public class Verified : DependencyObject
{
    public static readonly DependencyProperty VerifiedUserNameProperty = DependencyProperty.Register(
        "VerifiedUserName",
        typeof(string),
        typeof(Verified),
        new PropertyMetadata(string.Empty)
    );
    public string VerifiedUserName
    {
        get { return (string)GetValue(VerifiedUserNameProperty); }
        set { SetValue(VerifiedUserNameProperty, value); }
    }
    public static readonly DependencyProperty IsVerifiedProperty = DependencyProperty.Register(
        "IsVerified",
        typeof(bool),
        typeof(Verified),
        new PropertyMetadata(false, new PropertyChangedCallback(IsVerifiedChanged))
    );
    public bool IsVerified
    {
        get { return (bool)GetValue(IsVerifiedProperty); }
        set { SetValue(IsVerifiedProperty, value); }
    }
    private static void IsVerifiedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Verified container = d as Verified;
        bool latestIsVerifiedValue = (bool)e.NewValue;
        if (latestIsVerifiedValue == true)
        {
            //To Do
        }
    }
}

在我的 App.xaml 中,我创建了变量:

public static Verified myValidator = new Verified();
public static BooleanToVisibilityConverter myConverter = new BooleanToVisibilityConverter();

在一个简单的页面中,我添加了一个文本框,我想将其可见性绑定到 myValidator 变量。

为了实现这一点,我在代码中创建绑定:

Binding myBinding = new Binding();
myBinding.Source = App.myValidator;
myBinding.Path = new PropertyPath("IsVerified");
myBinding.Mode = BindingMode.OneWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
myBinding.Converter = App.myConverter;
BindingOperations.SetBinding(txtName2, VisibilityProperty, myBinding);

在 App.xaml 中:我以这种方式设置验证器的值:

App.myValidator.IsVerified = false;

当我导航到简单页面时,文本框不可见(确定)。

为了测试行为,我在屏幕上添加了一个按钮,并添加了代码来更改myValidator.isVerified的值。

当我更改我的 App.myValidator.IsVerify 的值时,文本框的可见性不会改变。如何解决问题?

绑定系统使用反射来查找属性,它不查找"字段"。

当您声明时

public static Verified myValidator = new Verified();

您声明的是字段,而不是属性。

将 App.cs 中的 myValidator 更改为属性可以解决此问题,如下所示,

public static Verified myValidator { get; set; } = new Verified();

更新!它起作用的原因是因为我不小心在 MainPage 中声明了一个已验证的属性.cs,

public sealed partial class MainPage : Page
{
    public Verified myValidator1 {get; set;} // the property name does not matter
    public MainPage()
    {
        this.InitializeComponent();
    }
}

不知道为什么它有效,我仍在研究它。

基本问题是属性没有发送更改的事件,因此绑定甚至不知道属性已更改,更不用说它应该调用转换方法了。实现INotifyPropertyChanged应在属性更改时通知它,然后它应调用转换器并执行所需的操作。

首先,我可以在我这边重现这个问题。为了验证根本原因,我注册了 Verified.IsVerifiedProperty 的 PropertyChanged 回调:

private long token;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
            token = App.myValidator.RegisterPropertyChangedCallback(Verified.IsVerifiedProperty, ChangedCallback);
            base.OnNavigatedTo(e);
}
private void ChangedCallback(DependencyObject sender, DependencyProperty dp)
{
            if (dp == Verified.IsVerifiedProperty)
            {
                System.Diagnostics.Debug.WriteLine("ChangedCallback" + sender.GetValue(dp));
                System.Diagnostics.Debug.WriteLine("ChangedCallback" + txtName2.Visibility);
            }
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
            App.myValidator.UnregisterPropertyChangedCallback(Verified.IsVerifiedProperty, token);
            base.OnNavigatedFrom(e);
}

无法按预期触发 PropertyChanged,因此解决方案是为 Verified 类实现 INotifyPropertyChanged 接口:

public class Verified : DependencyObject, INotifyPropertyChanged
{
        public static readonly DependencyProperty IsVerifiedProperty = DependencyProperty.Register(
            "IsVerified",
            typeof(bool),
            typeof(Verified),
            new PropertyMetadata(false, new PropertyChangedCallback(IsVerifiedChanged))
        );
        public bool IsVerified
        {
            get { return (bool)GetValue(IsVerifiedProperty); }
            set { SetValue(IsVerifiedProperty, value);
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs("IsVerified"));
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private static void IsVerifiedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Verified container = d as Verified;
            bool latestIsVerifiedValue = (bool)e.NewValue;
            if (latestIsVerifiedValue == true)
            {
                //To Do
            }
        }
}

最新更新