Win表单中的单变量绑定:我做错了什么?

时间:2015-11-16 21:00:35

标签: c# .net winforms binding inotifypropertychanged

我一直在尝试为WinForm中的两个标签进行绑定工作,但我似乎无法弄清楚我做错了什么。目前,我正在实现INotifyPropertyChanged接口,并将其绑定到表单中的几个属性。这影响的当前类是SessionForm.cs,实际形式,Session.cs,我保存程序的所有信息的地方。有问题的标签,在两个类中都没有提到,是L_No,它包含音乐标尺中Note的数字参考,L_Note,它包含内脏Note值(例如C,C#等)。

请允许我解释一下课程中的所有内容。该程序旨在通过根据您选择的比例询问您对比例的n th 注释来测试您的比例知识。您可以使用表单上的按钮进行选择。

这些选项记录在Session类中,已编辑该类以使其更简洁。整数数组包含与scale数组相关的音符索引,该数组位于Scale对象中。例如,典型的Note数组可能包含以下值:{1,3,0,2,6,1,3,...}。通过使用Scale对象中的数组作为参考,这些将转换为音符(例如D,F,C,E,B,D,F,......)。玩家的选择存储在NoteData个对象的数组中。

SessionForm.cs我随着时间的推移操纵这些信息。每次做出或不做出选择时(取决于他们是否试图及时猜测),两个标签的值都会改变:L_No和L_Note。这两个标签分别由变量NoteIndex和LastNote操纵。当这些值发生变化时,会发生NotifyPropertyChanged,然后标签更新......但他们没有这样做。

现在,在表单的设计部分,在“属性”窗口中,我将每个Label的Text属性设置为绑定到表单中各自的变量,并设置为在属性更改时更新,但似乎没有工作。

那么我做错了什么?

Session.cs

    public class Session
    {
        public struct NoteData
        {
            public int Note;
            public bool Correct;
            public int GuessTime;
        }

        public Scale Scale;

        /// <summary>
        /// Holds the notes for one game
        /// </summary>
        public int[] Notes { get; private set; }

        public NoteData[] Data { get; private set; }

        /// <summary>
        /// Creates a  Session
        /// </summary>
        /// <param name="difficulty">The difficult of the session, refer to the Resources Class for determination.</param>
        /// <param name="scale_used">The scale to be used. Refer to the Resources Class for determination.</param>
        /// <param name="notes">The notes being used within this Session</param>
        public Session(Resources.Difficulties difficulty, Scale scale_used, int[] notes)
        {
            ID = DateTime.Now;
            Diff = difficulty;
            Scale = scale_used;
            Notes = notes;
            Data = new NoteData[notes.Length];
            internalIndex = 0;
        }

        /// <summary>
        /// Stores Note input for each guessed
        /// </summary>
        /// <param name="index">The index of the note the player is currently on</param>
        /// <param name="correct">Was the guess correct?</param>
        /// <param name="remaining_time">How long did it take for them to guess?</param>
        public void StoreNoteInput(int index, bool correct, int remaining_time)
        {
            if (internalIndex < Data.Length)
                Data[internalIndex++] = new NoteData(index, remaining_time, correct);
        } 


}

SessionForm.cs

    public partial class SessionForm : Form, INotifyPropertyChanged
    {
        public Session curSession { get; private set; }
        Resources.Notes last_note;
        /// <summary>
        /// The note index number in relation to the scale
        /// </summary>
        public int NoteIndex
        {
            get
            { return note_index; }
            private set
            {
                if (note_index != value)
                {
                    note_index = value;
                    NotifyPropertyChanged("NoteIndex");
                }
            }
        }
        /// <summary>
        /// Represents the previous note being tested
        /// </summary>
        public Resources.Notes LastNote
        {
            get
            {
                return last_note;
            }
            private set
            {
                if (last_note != value)
                {
                    last_note = value;
                    NotifyPropertyChanged("LastNote");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        private void TickDownTimer_Tick(object sender, EventArgs e)
        {
            remainingTime -= countingDown ? 1000 : 100;
            if (remainingTime == 0)
            {
                if (countingDown)
                {
                    countingDown = false;
                    TickDownTimer.Interval = 100;
                }
                if (curIndex > 0)
                {
                    //you ran out of time on the last note
                    RecordNoteInput(curIndex - 1, false);


                }
                NextNote();
            }
            SetTimerText();
        }

        private void RecordNoteInput(int index, bool correct)
        {
            curSession.StoreNoteInput(index, correct, remainingTime);
            NoteIndex = curSession.Notes[curIndex - 1];
            LastNote = curSession.Scale.Notes[NoteIndex];
            L_Note.ForeColor = correct ? Color.Green : Color.Red;
        }

        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

更新:这是来自SessionForm.Designer.cs的绑定代码:

            this.sessionFormBindingSource1 = new System.Windows.Forms.BindingSource(this.components);
            this.sessionFormBindingSource2 = new System.Windows.Forms.BindingSource(this.components);
            this.sessionFormBindingSource = new System.Windows.Forms.BindingSource(this.components);
            // 
            // L_Note
            // 
            this.L_Note.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.sessionFormBindingSource1, "LastNote", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged, "C"));
            this.L_Note.Text = " ";
            // 
            // L_No
            // 
            this.L_No.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.sessionFormBindingSource2, "NoteIndex", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged, "1", "N0"));
            this.L_No.Text = " ";

1 个答案:

答案 0 :(得分:2)

问题在于您拨打NotifyPropertyChanged的方式:

NotifyPropertyChanged("note_index");

NotifyPropertyChanged("last_note");

只需从这样的调用中删除字符串

NotifyPropertyChanged();

一切都应该没问题。

编辑:如果不是,那么您的绑定未正确初始化。证明:

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Forms;

namespace Tests
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new TestForm());
        }
    }
    class TestForm : Form, INotifyPropertyChanged
    {
        public TestForm()
        {
            var label = new Label { Parent = this, Left = 16, Top = 16, AutoSize = false, BorderStyle = BorderStyle.FixedSingle };
            label.DataBindings.Add("Text", this, "NoteIndex");
            var timer = new Timer { Interval = 200, Enabled = true };
            timer.Tick += (sender, e) => NoteIndex = (NoteIndex + 1) % 10;
        }
        int note_index;
        public int NoteIndex
        {
            get { return note_index; }
            private set
            {
                if (note_index != value)
                {
                    note_index = value;
                    NotifyPropertyChanged();
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}