簡體   English   中英

試圖做兩種方式綁定 INotifyPropertyChanged null

[英]Trying to do two way binding INotifyPropertyChanged null

應該發生的是,由於計時器,我擁有的復選框會來回閃爍。 變量改變,但形式不變。 兩邊都勾選了dataMember的名字。

旨在與此處的 INotifyPropertyChanged 實現類似的類: 實現 INotifyPropertyChanged - 是否存在更好的方法?

using System;
using System.Collections.Generic;
using System.ComponentModel;

namespace Notice
{
    public class Notifier : INotifyPropertyChanged
    {
        //used to prevent infinite loops
        private bool controllerChanged;
        public event PropertyChangedEventHandler PropertyChanged;
        public Notifier()
        {
            controllerChanged = false;
        }
        public bool SetField<T>(ref T field, T value, string propertyName)
        {
            if (!controllerChanged)
            {
                controllerChanged = true;
                if (EqualityComparer<T>.Default.Equals(field, value))
                {
                    controllerChanged = false;
                    return false;
                }
                field = value;
                OnPropertyChanged(propertyName);
                controllerChanged = false;
                return true;

            }
            return false;
        }

        protected virtual void OnPropertyChanged(string property)
        {
            //PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));

            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }

        }

    }
}

類變量,僅舉一個例子

using System;
using Notice;

namespace Vars
{
    public class Checks
    {

        private bool checkbox;

        Notifier note = new Notifier();
        public Checks()
        {
            checkbox = true;

        }

        public bool Checkbox 
        { 
            get { return checkbox; }
            //set { WindowsFormsApp1.Program.note.SetField(ref checkbox, value, "Checkbox"); }
            set { note.SetField(ref checkbox, value, "Checkbox"); }
        }


    }
}

大部分表單代碼:

public Form1()
        {
            InitializeComponent();
            //If you bind it using properties for the item in the form, don't need this line
            checkBox1.DataBindings.Add("Checked", WindowsFormsApp1.Program.Ch, "Checkbox", true, DataSourceUpdateMode.OnPropertyChanged);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            WindowsFormsApp1.Program.Ch.Checkbox = !WindowsFormsApp1.Program.Ch.Checkbox;
            Console.WriteLine(WindowsFormsApp1.Program.Ch.Checkbox);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            WindowsFormsApp1.Program.Ch.Checkbox = !WindowsFormsApp1.Program.Ch.Checkbox;
            Console.WriteLine(WindowsFormsApp1.Program.Ch.Checkbox);
        }

雖然“更喜歡組合而不是繼承”這句話經常出現,但在這里你已經走得太遠了。

INotifyPropertyChanged接口依賴於事件的sender是屬性本身所在的同一對象。 在您的實現中,您已將事件委托給一個根本不向公眾公開的對象,即使 XAML 可以從該對象接收通知,該對象也不是屬性所在的對象。

你應該:

  1. Make Checks繼承Notifier類而不是組合一個
  2. SetField()方法設置為protected而不是public ,並直接從屬性 setter 中調用它,而不是通過Notifier的中間實例

就其價值而言,通常不需要您添加到規范實現中的controllerChanged功能。 不會發生遞歸,因為當設置的值與當前值相同時不會發出通知。 如果您遇到遞歸問題,您可能正在做其他不正確的事情,例如嘗試切換值以響應通知。 在這種情況下,將遞歸短路可避免堆棧溢出,但會隱藏導致它的代碼中的真正錯誤。

我建議也刪除controllerChanged功能。 如果沒有它的代碼有問題,請發布一個新問題,確保包含一個可靠地重現堆棧溢出的良好 [mcve],解釋您已經嘗試過的修復方法,以及您具體需要什么幫助和。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM