通过后面的代码设置时,两种方式绑定不起作用

Posted

技术标签:

【中文标题】通过后面的代码设置时,两种方式绑定不起作用【英文标题】:Two Way binding not working when set via Code behind 【发布时间】:2017-08-04 10:08:21 【问题描述】:

我在后面的代码中创建动态控件,并将其可见性属性绑定到后面的代码中的属性。但是当属性值改变时,它不会更新控件的可见性。

绑定:

        Binding assetsVisibilityBinding = new Binding();
        assetsVisibilityBinding.Source = this;
        assetsVisibilityBinding.Path = new PropertyPath("IsLocalSearchEnabled");
        assetsVisibilityBinding.Mode = BindingMode.TwoWay;
        assetsVisibilityBinding.Converter = Resources["BooleanToVisibilityConverter"] as IValueConverter;
        assetsStackPanel.SetBinding(StackPanel.VisibilityProperty, assetsVisibilityBinding);

属性(使用 fody):

  public bool IsLocalSearchEnabled  get; set; 

【问题讨论】:

我要做的第一件事是在 justDecompile 中打开已编译的二进制文件,并确保 fody 实际上正在重写您的程序集。此外,使用 Snoop 之类的工具(不确定它是否适用于 uwps)在运行时检查您的绑定。 【参考方案1】:

也许你的包含属性的类需要实现接口

INotifyPropertyChanged

假设您的班级名称是 A

那么sn-p就是

class A : INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    
        var handler = PropertyChanged;
        if (handler != null)
        
            handler(this, new PropertyChangedEventArgs(propertyName));
        
    

    public bool isLocalSearchEnabled = false;
    public bool IsLocalSearchEnabled
    
         get  return isLocalSearchEnabled ;
         set  isLocalSearchEnabled  = value; this.OnPropertyChanged("IsLocalSearchEnabled");
    

当你实现 INotifyPropertyChanged 时,这里发生的是事件 PropertyChanged 当设置 isLocalSearchEnabled 的值时触发(不考虑旧值和新值)并使用公共属性的名称调用 OnPropertyChanged

【讨论】:

谢谢。但正如帖子中提到的,我实际上使用的是 Fody(github.com/Fody/PropertyChanged)。它会自动实现【参考方案2】:

你好像没有实现INotifyPropertyChanged接口,详细例子请看INotifyPropertyChanged

【讨论】:

谢谢。但正如帖子中提到的,我实际上使用的是 Fody(github.com/Fody/PropertyChanged)。它会自动实现。【参考方案3】:

你是否设置了 assetsStackPanel DataContext 绑定需要源,你应该设置 DataContext 只设置源。

如果您在 xaml.cs 中设置了 this 中的属性,您应该将其公开。

Binding assetsVisibilityBinding = new Binding();
        assetsVisibilityBinding.Source = this;
        assetsVisibilityBinding.Path = new PropertyPath("IsLocalSearchEnabled");
        assetsVisibilityBinding.Mode = BindingMode.TwoWay;
        assetsVisibilityBinding.Converter = Resources["BooleanToVisibilityConverter"] as IValueConverter;
        assetsStackPanel.DataContex=this;
        assetsStackPanel.SetBinding(StackPanel.VisibilityProperty, assetsVisibilityBinding);

由于我没有读过frameWork,我想你可以尝试使用INotifyPropertyChanged的属性来判断代码是否正确。

你可以使用BindingOperations.SetBinding

尝试在 xaml 中使用 resharper 并编写 Visibility="Binding RelativeSource=RelativeSource AncestorType=Window,Path=IsLocalSearchEnabled",mode=TwoWay。如果它可以工作,则意味着 FrameWork 可以工作。

【讨论】:

【参考方案4】:

谢谢。但正如帖子中提到的,我实际上正在使用 福迪(github.com/Fody/PropertyChanged)。哪个自动实现 那个

我已经检查了编译的类,通过使用Fody PropertyChanged 属性更改通知没有成功实现

[ImplementPropertyChanged]
public sealed partial class MainPage : Page

    public bool IsLocalSearchEnabled  get; set; 

    public MainPage()
    
        this.InitializeComponent();
        SetBinding();
        this.DataContext = this;
    

    public void SetBinding()
    
        Binding assetsVisibilityBinding = new Binding();
        assetsVisibilityBinding.Source = this;
        assetsVisibilityBinding.Path = new PropertyPath("IsLocalSearchEnabled");
        assetsVisibilityBinding.Mode = BindingMode.TwoWay;
        assetsVisibilityBinding.Converter = Resources["BooleanToVisibilityConverter"] as IValueConverter;
        assetsStackPanel.SetBinding(StackPanel.VisibilityProperty, assetsVisibilityBinding);
    

我建议你向 Fody 报告问题以解决它。

标准方式如下:

public sealed partial class MainPage : Page, INotifyPropertyChanged

    bool isLocalSearchEnabled;
    public bool IsLocalSearchEnabled
    
        get  return isLocalSearchEnabled; 
        set
        
            if (value != isLocalSearchEnabled)
            
                isLocalSearchEnabled = value;
                OnPropertyChanged("IsLocalSearchEnabled");
            
        
    

    public MainPage()
    
        this.InitializeComponent();
        SetBinding();
        this.DataContext = this;
    

    public void SetBinding()
    
        Binding assetsVisibilityBinding = new Binding();
        assetsVisibilityBinding.Source = this;
        assetsVisibilityBinding.Path = new PropertyPath("IsLocalSearchEnabled");
        assetsVisibilityBinding.Mode = BindingMode.TwoWay;
        assetsVisibilityBinding.Converter = Resources["BooleanToVisibilityConverter"] as IValueConverter;
        assetsStackPanel.SetBinding(StackPanel.VisibilityProperty, assetsVisibilityBinding);
    

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    

或者您可以轻松使用包装类:BindableBase

【讨论】:

以上是关于通过后面的代码设置时,两种方式绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章

设置DataContext后WPF依赖属性两种方式绑定不起作用[重复]

@Input:两种方式数据绑定不起作用

在 Angular 2 中,当我尝试使用两种方式绑定时,ngIF 不起作用

Select2 for AngularJS 中的两种方式数据绑定不起作用

在协程内触发时双向数据绑定不起作用

Vue-google-map 自动完成两种方式绑定不起作用