我试图将控件的可见性绑定到全局变量:
我有一个可见性转换器:
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中:我以这种方式设置我的Validator的值:
App.myValidator.IsVerified = false;
当我导航到简单页面时,文本框不可见(确定)。
为了测试行为,我在屏幕上添加了一个按钮,并添加了代码来更改myValidator.isVerified的值。
当我更改App.myValidator.IsVerified的值时,文本框的可见性不会改变。我该如何解决这个问题呢?
答案 0 :(得分:3)
绑定系统使用反射来查找属性,它不会查找"字段"。
宣布
时public static Verified myValidator = new Verified();
您正在声明一个字段,而不是一个属性。
将App.cs中的myValidator更改为属性可以解决问题,如下所示,
public static Verified myValidator { get; set; } = new Verified();
更新! 它起作用的原因是因为我不小心在MainPage.cs中声明了一个Verified属性,
public sealed partial class MainPage : Page
{
public Verified myValidator1 {get; set;} // the property name does not matter
public MainPage()
{
this.InitializeComponent();
}
}
不确定为什么会有效,我还在调查它。
答案 1 :(得分:1)
基本问题是您的财产没有发送更改的事件,因此您的绑定甚至不知道该属性已更改,更不用说它应该调用您的转换方法。实现INotifyPropertyChanged
时应该在属性更改时通知它,然后它应该调用转换器并执行您想要的操作。
答案 2 :(得分:0)
首先,我可以在我身边重现这个问题。 为了验证根本原因,我注册了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
}
}
}