Maybe I'm having a dumb day...
I'm having some "fun" trying to force a tool-strip to trigger
validation, i.e. so that the last (bound) control being edited updates
the model with changes. Can anybody see what I am doing daft? The
"save" in this case writes the values into the Form's caption - if you
are mid-edit then the last committed value is used - which risks data
loss.
All I want to do is force validation, as though a regular Control was
used (see the Button in this code below). For now (in the actual code)
I've hacked it by switching control in the handler - but this is not
very pleasing; any input?
Marc
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections.Generic;
// just a data class that supports notification
sealed class SomeData : INotifyPropertyChanged {
private bool UpdateField<T>(ref T field, T value, string
propertyName) {
if (EqualityComparer<T>.Default.Equals(field, value)) return
false; // no change
field = value;
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new
PropertyChangedEventArgs(propertyName));
return true;
}
private string name = "Fred";
private int size = 24;
public string Name {
get { return name; }
set { UpdateField(ref name, value, "Name"); }
}
public int Size {
get { return size; }
set { UpdateField(ref size, value, "Size"); }
}
public event PropertyChangedEventHandler PropertyChanged;
}
// a form with 2 save buttons; one Button, one ToolStripButton
sealed class Demo : Form {
readonly SomeData data = new SomeData();
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Demo());
}
private void AddEditor(string property) {
TextBox tb = new TextBox();
tb.Name = "Editor_" + property;
tb.Dock = DockStyle.Top;
Binding b = tb.DataBindings.Add("Text", data, property);
b.ControlUpdateMode = ControlUpdateMode.OnPropertyChanged;
b.DataSourceUpdateMode = DataSourceUpdateMode.OnValidation;
Controls.Add(tb);
tb.BringToFront();
}
Demo() {
ToolStrip ts = new ToolStrip();
ts.Items.Add("Save fails (old values used)", null,
Save_Click);
ts.Dock = DockStyle.Top;
ts.CausesValidation = true;
Controls.Add(ts);
Button btn = new Button();
btn.Text = "Save works (new values used)";
btn.CausesValidation = true;
btn.Click += Save_Click;
btn.Dock = DockStyle.Top;
Controls.Add(btn);
btn.BringToFront();
AddEditor("Name");
AddEditor("Size");
AddEditor("Name");
AddEditor("Size");
}
void Save_Click(object sender, EventArgs args) {
Text = data.Name + " : " + data.Size;
}
}