I'm struggling with the AddingNew event on BindingList.
This is my code: the ListChanged is fired, the AddingNew not.
I'm missing something?
{
//....
System.ComponentModel.BindingList<string> test = new System.ComponentModel.BindingList<string>();
test.AllowNew = true;
test.RaiseListChangedEvents = true;
test.AddingNew += Test_AddingNew;
test.ListChanged += Test_ListChanged;
test.Add(new string("test1"));
test.Add("test2");
//....
}
private void Test_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
throw new NotImplementedException();
}
private void Test_AddingNew(object sender, System.ComponentModel.AddingNewEventArgs e)
{
throw new NotImplementedException();
}
I know this is old, but I was having the same issue. AddingNew is ONLY fired when BindingList.AddNew() is called. It is not called when BindingList.Add() is called.
Therefore either .ListChanged will need to be used or AddNew() will be required to fire the event.
Its working for me, but what is this? - new string("test1") <- remove it
class Program
{
static void Main(string[] args)
{
//....
System.ComponentModel.BindingList<string> test = new System.ComponentModel.BindingList<string>();
test.AllowNew = true;
test.RaiseListChangedEvents = true;
test.AddingNew += Test_AddingNew;
test.ListChanged += Test_ListChanged;
test.Add("test1");
test.Add("test2");
}
private static void Test_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e)
{
throw new NotImplementedException();
}
private static void Test_AddingNew(object sender, System.ComponentModel.AddingNewEventArgs e)
{
throw new NotImplementedException();
}
}
Related
My application in C# has a Textbox with a txt_TextChanged event.
private void txt_TextChanged(object sender, EventArgs e)
{
//Do somthin
}
But there's one specific part that I want to change txt.Text without firing the txt_TextChanged event.
txt.Text ="somthing" //Don't fire txt_TextChanged
How can I do that?
There is no direct way to prevent the raising of events for the text property, however your event handler can use a flag to determine weather or not to perform a task. This i likely to be more efficient than attaching and detaching the event handler. This can be done by a variable within the page or even a specialized class wrapper
With a variable:
skipTextChange = true;
txt.Text = "Something";
protected void TextChangedHandler(object sender, EventArgs e) {
if(skipTextChange){ return; }
/// do some stuffl
}
With specialized event handler wrapper
var eventProxy = new ConditionalEventHandler<EventArgs>(TextBox1_TextChanged);
TextBox1.TextChanged = eventProxy.EventAction;
eventProxy.RaiseEvents = false;
TextBox1.Text = "test";
public void TextBox1_TextChanged(object sender, EventArgs e) {
// some cool stuff;
}
internal class ConditionalEventHadler<TEventArgs> where TEventArgs : EventArgs
{
private Action<object,TEventArgs> handler;
public bool RaiseEvents {get; set;}
public ConditionalEventHadler(Action<object, TEventArgs> handler)
{
this.handler = handler;
}
public void EventHanlder(object sender, TEventArgs e) {
if(!RaiseEvents) { return;}
this.handler(sender, e);
}
}
txt.TextChanged -= textBox1_TextChanged; // dettach the event handler
txt.Text = "something"; // update value
txt.TextChanged += textBox1_TextChanged; // reattach the event handler
You can extend text box and introduce there a new property that will not trigger the TextChanged event.
class SilentTextBox : TextBox
{
// if true, than the TextChanged event should not be thrown
private bool Silent { get; set; }
public string SilentText
{
set
{
try
{
Silent = true;
Text = value;
}
finally
{
Silent = false;
}
}
}
protected override void OnTextChanged(EventArgs e)
{
// raise event only if the control is in non-silent state
if (!Silent)
{
base.OnTextChanged(e);
}
}
}
try this extension method
public static class TextBoxExt
{
private static readonly FieldInfo _field;
private static readonly PropertyInfo _prop;
static TextBoxExt()
{
Type type = typeof(Control);
_field = type.GetField("text", BindingFlags.Instance | BindingFlags.NonPublic);
_prop = type.GetProperty("WindowText", BindingFlags.Instance | BindingFlags.NonPublic);
}
public static void SetText(this TextBox box, string text)
{
_field.SetValue(box, text);
_prop.SetValue(box, text, null);
}
}
you can use textbox.SetText("...") to change text and the TextChanged event will not be fired.
A quick and dirty way is to do an
ctrl.Enable = false;
ctrl.Text = "Something";
ctrl.Enable = true;
and then in the OnChange event, encapsulate the offending code with a
if (ctrl.Enabled) {
// offending code here.
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
EventHandler TextChanged_EventHandler = new EventHandler(textBox1_TextChanged);
textBox1.TextChanged -= TextChanged_EventHandler;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
MessageBox.Show("BUG");
}
}
I found a simple method, suitable for event handlers and controls that are not in the same .cs file
public static void SetTextWithoutRaiseEvent(this TextBox textBox, string content)
{
var scroll = textBox.Template.FindName("PART_ContentHost", textBox);
(scroll as ScrollViewer).Content = content;
}
I create a FileSystemWatcher on a separate thread to monitor a directory for changes. None of my events fire when I add a new file or copy a new file into the directory that I am trying to monitor. I've used the FileSystemWatcher class successfully in Windows Forms apps, so I am guessing I am missing something simple.
public partial class MainWindow : Window
{
System.IO.FileSystemWatcher watcher;
public MainWindow()
{
InitializeComponent();
System.Threading.Thread t1 = new System.Threading.Thread(MonitorDir);
t1.IsBackground = true;
t1.Start();
}
private void MonitorDir()
{
watcher = new System.IO.FileSystemWatcher("C:\\Temp","*.*");
watcher.Created += Watcher_Created;
watcher.Disposed += Watcher_Disposed;
watcher.Error += Watcher_Error;
watcher.Changed += Watcher_Changed;
while (true)
{
}
}
private void Watcher_Changed(object sender, System.IO.FileSystemEventArgs e)
{
throw new NotImplementedException();
}
private void Watcher_Error(object sender, System.IO.ErrorEventArgs e)
{
throw new NotImplementedException();
}
private void Watcher_Disposed(object sender, EventArgs e)
{
throw new NotImplementedException();
}
private void Watcher_Created(object sender, System.IO.FileSystemEventArgs e)
{
throw new NotImplementedException();
}
}
You need to set its EnableRaisingEvents property to true (it's false by default), otherwise it won't raise any events.
watcher.EnableRaisingEvents = true;
What is the difference between -= new EventHandler(Method) to -= Method
when the method passing as parameter?
Why does the removeNew failed to unsubscribe?
see the following class:
public class Class1
{
public EventHandler _eh;
public void OnEvent()
{
if (_eh != null)
{
_eh.Invoke("", new EventArgs());
}
}
public void remove(EventHandler evHandler)
{
// unsubscribe successfully
_eh -= evHandler;
}
public void removeNew(EventHandler evHandler)
{
// failed to unsubscribe
_eh -= new EventHandler(evHandler);
}
}
Update:
#SchabseLaks, just to clearify my questation I'm adding the code that call this methods:
public partial class Form1 : Form
{
Class1 c1 = new Class1();
public Form1()
{
InitializeComponent();
c1._eh += Hello;
}
private void button1_Click(object sender, EventArgs e)
{
c1.OnEvent();
}
private void Hello(object sender, EventArgs e)
{
MessageBox.Show("hello");
}
private void button2_Click(object sender, EventArgs e)
{
c1.removeNew(Hello);
}
private void button3_Click(object sender, EventArgs e)
{
c1.remove(Hello);
}
}
A delegate can only be created from a method.
new EventHandler(evHandler) is shorthand for new EventHandler(evHandler.Invoke), because Invoke is the method on any delegate type that actually calls the delegate.
Since your _eh doesn't have evHandler.Invoke as a handler, that does nothing.
The syntax of EventHandler is often confusing. The key to understanding it is to realise it overrides the Equals operator such that one EventHandler is equal to another because they hold the same Delegate (or list of delegates) as the events target(s).
So;
var x = new EventHandler(myDelegate);
var y = new EventHandler(myDelegate);
Assert.IsTrue(x == y);
var x = new EventHandler(myDelegate);
var y = new EventHandler(anotherDelegate);
Assert.IsFalse(x == y);
When you += or -= a new instance of EventHandler such as
myHandler -= new EventHandler(someDelegate);
the new EventHander is passed into the decrement method of the myHandler instance where its target delegate is compared to those already in the list. Its the Target that is being removed, not the new EventHandler instance. Conversely when you;
myHandler += new EventHandler(someDelegate);
The someDelegate is added to the existing list of delegates on the target multicast delegate called myHandler. The new EventHandler is discarded and is just a cargo carrier for that single increment method call.
Right I have the following code:
public partial class Form1 : Form
{
delegate void UpdateUI();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
if (!Fiddler.CertMaker.rootCertExists())
{
if (!Fiddler.CertMaker.createRootCert())
{
throw new Exception("Unable to create cert for FiddlerCore.");
}
}
if (!Fiddler.CertMaker.rootCertIsTrusted())
{
if (!Fiddler.CertMaker.trustRootCert())
{
throw new Exception("Unable to install FiddlerCore's cert.");
}
}
Fiddler.FiddlerApplication.OnNotification += delegate (object snder, NotificationEventArgs oNEA) { MessageBox.Show("** NotifyUser: " + oNEA.NotifyString); };
Fiddler.FiddlerApplication.Log.OnLogString += delegate (object snder, LogEventArgs oLEA) { MessageBox.Show("** LogString: " + oLEA.LogString); };
Fiddler.FiddlerApplication.AfterSessionComplete += FiddlerApplication_OnAfterSessionComplete;
Fiddler.FiddlerApplication.Startup(0, FiddlerCoreStartupFlags.Default & FiddlerCoreStartupFlags.DecryptSSL);
}
void FiddlerApplication_OnAfterSessionComplete(Session oSession)
{
if(oSession.fullUrl.Contains("google.com"))
richTextBox1.Invoke(new UpdateUI(() =>
{
richTextBox1.AppendText(oSession.GetResponseBodyAsString());
}));
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Fiddler.FiddlerApplication.Shutdown();
}
}
The thing is with DecryptSSL flag set on startup the on aftersesssion complete never fires, I also never get any messages from either the notification or logs callbacks.
Any ideas?
I think port 0 might be a problem in the Startup(), I tried with port 8888:
Fiddler.FiddlerApplication.Startup(8888, FiddlerCoreStartupFlags.Default & FiddlerCoreStartupFlags.DecryptSSL);
I tried with these before response and before request handlers instead of OnAfterSessionComplete. In your Form1_Load():
Fiddler.FiddlerApplication.BeforeRequest += new SessionStateHandler(HandleBeforeRequest);
Fiddler.FiddlerApplication.BeforeResponse += new SessionStateHandler(HandleBeforeResponse);
And the handlers:
private void HandleBeforeRequest(Session oSession)
{
oSession.bBufferResponse = true;
}
private void HandleBeforeResponse(Session oSession)
{
if(oSession.fullUrl.Contains("google.com"))
{
richTextBox1.Invoke(new UpdateUI(() =>
{
richTextBox1.AppendText(oSession.GetResponseBodyAsString());
}));
}
}
By the way, don't know if you omitted them from your sample but I needed to add these in the constructor:
Load += Form1_Load;
FormClosing += Form1_FormClosing;
Might also be good to add this before Shutdown():
FiddlerApplication.oProxy.Detach();
Here is my code in my userControl
public partial class UserControlHomeScreen : UserControl
{
public event EventHandler SomethingHappened;
public void DoSomething()
{
EventHandler handler = SomethingHappened;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
public void HandleEvent(object sender, EventArgs args)
{
MessageBox.Show("Wafak.");
}
public UserControlHomeScreen()
{
InitializeComponent();
}
private void btnAverageDailyBal_Click(object sender, EventArgs e)
{
this.Tag = 0;
this.Hide();
}
private void btnComputeTransferPricing_Click(object sender, EventArgs e)
{
this.Tag = 1;
this.Hide();
}
}
And here is my code in my main form
private void HomeScreen()
{
uHomeScreen = new UserControlHomeScreen();
uHomeScreen.Dock = DockStyle.Fill;
//uHomeScreen.Disposed += new EventHandler(uHomeScreen_Disposed);
uHomeScreen.SomethingHappened += new EventHandler(uHomeScreen_SomethingHappened);
panelMain.Controls.Add(uHomeScreen);
}
void uHomeScreen_SomethingHappened(object sender, EventArgs e)
{
MessageBox.Show("throw new NotImplementedException();");
}
What i want to happen is that when the usercontrol is hidden i want to fire an event in my main form but does not work, what am i missing? please help. thanks!
Your naming convention for event raiser (DoSomething) is confusing, your code doesn't call DoSomething (or raise the event SomethingHappened), so how could it fire for you? Add the following code in your user control class:
//override the OnVisibleChanged
protected override void OnVisibleChanged(EventArgs e){
if(!Visible) DoSomething();
}