【问题标题】: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)在运行时检查您的绑定。

标签: c# xaml mvvm uwp winrt-xaml


【解决方案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

【讨论】:

【解决方案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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-15
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2021-10-24
      • 2020-04-07
      • 2017-04-06
      相关资源
      最近更新 更多