【发布时间】:2016-02-18 02:12:52
【问题描述】:
我一直在尝试对 WinForm 中的两个标签进行绑定,但我似乎无法弄清楚我做错了什么。目前,我正在实现INotifyPropertyChanged 接口,并将其绑定到表单中的几个属性。受此影响的当前类是SessionForm.cs(实际形式)和Session.cs(我保存程序所有信息的地方)。有问题的标签在任何一个类中都没有提到,L_No,它保存音符在音阶中的数字引用,以及 L_Note,它保存本能音符值(例如 C、C# 等)。
请允许我解释一下类中的所有内容。该程序旨在通过根据您选择的音阶询问您音阶的第 nth 个音符是什么来测试您的音阶知识。您可以使用表单上的按钮做出选择。
这些选择记录在 Session 类中,该类已被编辑以使其更加简洁。整数数组保存与比例数组相关的音符索引,该数组位于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,然后标签应该被更新......但他们没有这样做。
现在,在表单的设计部分,在“属性”窗口中,我将每个标签的 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 = " ";
【问题讨论】:
-
您确认
NotifyPropertyChanged被解雇了吗?此外,虽然我感谢您尝试彻底,但在您的代码示例之上还有很多事情发生。如果您可以去除所有“噪音”并仅描述您在绑定时遇到的问题,您将更有可能获得帮助,即“标签L_NoteNo绑定到NoteIndex,但它不会改变NoteIndex的值发生变化。” -
@DrewJordan:我做了检查,不,我没有开火,我不知道为什么,我缩短了 OP。我添加了额外的内容,以防我错过了一些你可以看到系统工作的东西,而不仅仅是问题。我本可以这样做,但你不会明白随之发生的其他事情可能会弄乱它。
标签: c# .net winforms binding inotifypropertychanged