|
Well, the result changes when one or more of the inputs change, so what you really need to watch for is a change to the inputs. If this is on an object that implements change notification, you could pass that through and only check for a new result if the object reports a change.
But as for a changed event on the function itself... To my knowledge, no such thing exists. That function isn't going to re-run every time the inputs change, so the program doesn't even know what the new result is until you ask for it.
Off the top of my head, another alternative...
Instead of passing a function, wrap that up in a lightweight class:
public class FunctionWatcher
{
public FunctionWatcher(INotifyPropertyChanged caller, Delegate function)
{
}
private Delegate Callback;
public object Result { get; private set; }
public event EventHandler ResultChanged;
private void CallerPropertyChanged(...)
{
}
}
Again, this relies on having some object providing change notification... Otherwise your current solution might be the only one.
|
|
|
|
|
That sounds pretty good.
The reason for dealing with this is to have some kind of watcher that is able to be fed with Control objects in order to tell if
something has changed in one control or a group of controls and saving is required.
So I am dealing with List<Control> where Control does not provide the PropertyChanged interface.
I already implemented TextChanged for those Control objects to raise the "SomethingHasChangedEvent".
So far everything works fine.
The delegate option is an addon for cases where something else has to be watched instead of a Control object.
Let's assume a function that checks some DataGrid fields or whatever, cases where I do not want to register a lot of Controls to get a TextChanged handler attached.
After thinking about this for a while I recognized that asking the watcher if it is "dirty" and going through the delegate list for checking this might be enough.
On the other hand, why not providing this event, it might become useful later... yeah, and I like events too
The timer-idea just does not feel well... I have no idea how many work these delegates actually perform, so performance might become an issue later.
|
|
|
|
|
Hmm... Well, if you can get them all to raise some sort of change event, then you can just subclass a wrapper for each type... One to watch a control for TextChanged, one to watch an object implementing INotifyPropertyChanged, etc etc. They could all, in turn, raise the same change event after checking the result.
|
|
|
|
|
Good point Ian, I am just afraid that I am in a situation where I need to provide a fast and flexible solution... that's why I came up with the delegate stuff.
The people who wan't to use it can provide their own mechanism for resolving the original-value and the changed-value...
Just without an event...
I am really not sure if this event would be needed... maybe if some buttons will be disabled if changes have occured... but that's pretty much all I can think about.
I am not sure if I can implement INotifyPropertyChanged (I am used to work with this buddy in WPF - right now it's a WinForm app) on all circumstances...
Imagine a third party control that does not have a Text property or a TextChanged event.
Whatever this control is huge and does not implement INotifyPropertyChanged.
Right now I can pass a delegate to the watcher (it has AddControl(Control control) and AddDelegate(MyDelegate del) methods to add whatever is needed) and the one who uses the watcher can take care about whatever he thinks might be suitable to figure out if changes occured or not.
At that point I am unable to continue without subclassing something in order to bring the INotifyPropertyChanged into play.
I do not wan't the guyzos to change their objects or whatever... they should be able to implement it easily and without too much changes... on the other hand it is quite likely that the watcher will be heavily reused...
...where to go
What do you think?
|
|
|
|
|
Well, if the control doesn't raise any useful events, your options are limited, and the timer solution is about all there is (Just make sure it's sleeping between checks, not calling continuously).
Maybe you could hide the complexity with private classes... I'm still in favor of the wrappers to merge all the different possibilities into a single event type... When you pass in the control, it'll check for a few common types (For a TextBox, it would look for TextChanged. For a checkbox, CheckedChanged. If it's an INotifyPropertyChanged, PropertyChanged). Depending on the type of control passed, it creates a different wrapper that hooks the necessary event and supplies a simple Changed event. If it can't find an event to hook, it falls back to the timer method...
public void MonitorObject(object obj, Delegate valueToMonitor)
{
if (obj is TextBox)
Add(new TextChangedWatcher(obj as TextBox, valueToMonitor));
else if ...
else
Add(new DefaultObjectWatcher(obj, valueToMonitor));
}
private class ObjectWatcher
{
public event EventHandler Changed;
private Delegate ResultCallback { get; set; }
private object PreviousValue { get; set; }
protected void OnCheckValue()
{
object newValue = ResultCallback.Invoke();
if (!object.Equals(PreviousValue, newValue))
{
PreviousValue = newValue;
if (Changed != null) Changed(this, EventArgs.Empty);
}
}
}
private class TextChangedWatcher : ObjectWatcher
{
public TextChangedWatcher(TextBox ctl)
{
}
}
private class CheckedChangedWatcher : ObjectWatcher
{
}
private class NotifyObjectWatcher : ObjectWatcher
{
}
private class DefaultObjectWatcher : ObjectWatcher
{
}
Anyway... The idea would be to hook events when possible, and only fall back to the timer when there are no known events to hook.
|
|
|
|
|
Yes, you are right Ian.
I guess I'll go for the wrapper (I like wrappers anyway).
Maybe I'll replace the timer-part at a later time, but for now it'll suit my needs
Thank you Ian for your input, I really appreciate that,
best regards
Andy
|
|
|
|
|
Why is dynamic polymorphism so called? Want to know why not how it is achieved !
|
|
|
|
|
|
Here[^] are some reasons.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
Oh!! Thats the bunch from which I selected one.
|
|
|
|
|
Most of the link gives how to achieve dynamic polymorphism. I dint get an accurate answer
|
|
|
|
|
There's a fairly reasonable definition of dynamic polymorphism here[^].
|
|
|
|
|
maB_J wrote: I dint get an accurate answer
What do you mean by accurate? Did you read the first link in the list I sent you? It gives a full definition of Dynamic Polymorphism; you could also go to Bjarne Stroustrup's web site and read everything he has to say about it.
Just say 'NO' to evaluated arguments for diadic functions! Ash
|
|
|
|
|
hey guys..i try to add datas by stored procedure with 15 parameters..it works well..the problem is in my ProcessLayer..i have Firmalar class like below.
public class Firmalar
{
public string firma_adi { get; set; }
public string yetkili1 { get; set; }
public string gsm1 { get; set; }
public string email1 { get; set; }
public string yetkili2 { get; set; }
public string gsm2 { get; set; }
public string email2 { get; set; }
public string yetkili3 { get; set; }
public string gsm3 { get; set; }
public string email3 { get; set; }
public string telefon1 { get; set; }
public string telefon2 { get; set; }
public string telefon3 { get; set; }
public string telefon4 { get; set; }
public string telefon5 { get; set; }
}
and i try to add data in my processLayer like that
public void InsertFirm(Firmalar fir)
{
try
{
fir = new Firmalar();
cmmd = d.InsertData();
cmmd.Parameters.AddWithValue("@firmanin_adi", System.Data.SqlDbType.NVarChar).Value = fir.firma_adi;
cmmd.Parameters.AddWithValue("@yetkili1", System.Data.SqlDbType.NVarChar).Value = fir.yetkili1;
cmmd.Parameters.AddWithValue("@gsm_num1", System.Data.SqlDbType.NVarChar).Value = fir.gsm1;
cmmd.Parameters.AddWithValue("@e_mail1", System.Data.SqlDbType.NVarChar).Value = fir.email1;
cmmd.Parameters.AddWithValue("@yetkili2", System.Data.SqlDbType.NVarChar).Value = fir.yetkili2;
cmmd.Parameters.AddWithValue("@gsm_num2", System.Data.SqlDbType.NVarChar).Value = fir.gsm2;
cmmd.Parameters.AddWithValue("@e_mail2", System.Data.SqlDbType.NVarChar).Value = fir.email2;
cmmd.Parameters.AddWithValue("@yetkili3", System.Data.SqlDbType.NVarChar).Value = fir.yetkili3;
cmmd.Parameters.AddWithValue("@gsm_num3", System.Data.SqlDbType.NVarChar).Value = fir.gsm3;
cmmd.Parameters.AddWithValue("@e_mail3", System.Data.SqlDbType.NVarChar).Value = fir.email3;
cmmd.Parameters.AddWithValue("@tlfn1", System.Data.SqlDbType.NVarChar).Value = fir.telefon1;
cmmd.Parameters.AddWithValue("@tlfn2", System.Data.SqlDbType.NVarChar).Value = fir.telefon2;
cmmd.Parameters.AddWithValue("@tlfn3", System.Data.SqlDbType.NVarChar).Value = fir.telefon3;
cmmd.Parameters.AddWithValue("@tlfn4", System.Data.SqlDbType.NVarChar).Value = fir.telefon4;
cmmd.Parameters.AddWithValue("@tlfn5", System.Data.SqlDbType.NVarChar).Value = fir.telefon5;
cmmd.ExecuteNonQuery();
}
and inside of my form's code i try to send parameters...
private void btnEkle_Click(object sender, EventArgs e)
{
try
{
if (txtFirma_adi.Text.Length != 0)
{
firma = new Firmalar();
h.InsertFirm(firma);
firma.firma_adi = txtFirma_adi.Text;
firma.yetkili1 = txtYetkili_adi.Text;
firma.gsm1 = txtGsm.Text;
firma.email1 = txtEmail.Text;
firma.yetkili2 = txtYetkili2.Text;
firma.gsm2 = txtGsm2.Text;
firma.email2 = txtEmail2.Text;
firma.yetkili3 = txtTetkili3.Text;
firma.email3 = txtEmail3.Text;
firma.gsm3 = txtGsm3.Text;
firma.telefon1 = msktlf1.Text;
firma.telefon2 = mskTlf2.Text;
firma.telefon3 = mskTlf3.Text;
firma.telefon4 = msktlf4.Text;
firma.telefon5 = mskTlf5.Text;
}
}
}
but the values dont go to my stored procedure..and it gives error sp_AddDatas expects parameter @firmanin_adi...so how i can send the values to my stored procedure..
vemedya.com
|
|
|
|
|
erdinc27 wrote: fir = new Firmalar();
Inside method InsertFirm(Firmalar fir) why are you again intializing Object? Use the received object itself.
|
|
|
|
|
hey Hiren..thanks for the reply..i changed as u said and now it adds first parameter but not second parameter??
so why it happens ?
vemedya.com
|
|
|
|
|
erdinc27 wrote: cmmd.Parameters.AddWithValue("@yetkili1", System.Data.SqlDbType.NVarChar).Value = fir.yetkili1;
You have used blockquoted way to add parameter with value.
But AddWithValue having format of AddWithValue(string Parametername,object value)
Your statement must generate compile time error I think,
Use Like
cmmd.Parameters.AddWithValue("@yetkili1",fir.yetkili1);
|
|
|
|
|
i tried as u suggested but still nothing..it gives the same error..what else can be reason for that error ?
vemedya.com
|
|
|
|
|
Okey As you have done all suggested things.
Now Add one thing and see the magic.
After intializing command object which is cmmd, Put a line like.
cmmd.CommandType = CommandType.StoredProcedure
|
|
|
|
|
again me..i added the code u said but still no magic
u have any other suggesstion ?
vemedya.com
|
|
|
|
|
I think now you might have some problem with InsertData() Method. Can you show us that method,So that we can have better Idea of a whole scenario.
|
|
|
|
|
here is my InsertData()method
public SqlCommand InsertData()
{
cmd = new SqlCommand("sp_AddDatas", con);
cmd.CommandType = CommandType.StoredProcedure;
return cmd;
}
and here is the sp_AddDatas
ALTER procedure [dbo].[sp_AddDatas]
(
@firmanin_adi nvarchar(70),
@yetkili1 nvarchar(30),
@gsm_num1 nvarchar(20),
@e_mail1 nvarchar(30),
@yetkili2 nvarchar(30),
@gsm_num2 nvarchar(20),
@e_mail2 nvarchar(30),
@yetkili3 nvarchar(30),
@gsm_num3 nvarchar(20),
@e_mail3 nvarchar(30),
@tlfn1 nvarchar(20),
@tlfn2 nvarchar(20),
@tlfn3 nvarchar(20),
@tlfn4 nvarchar(20),
@tlfn5 nvarchar(20)
)
as
BEGIN
Insert Into Firmalar(firma_adi,yetkili_ad1,Gsm1,email1,yetkili_ad2,Gsm2,Email2,yetkili_ad3,Gsm3,Email3,Telefon1,Telefon2,Telefon3,Telefon4,Telefon5)Values (@firmanin_adi, @yetkili1,@gsm_num1,@e_mail1,@yetkili2,@gsm_num2,@e_mail2, @yetkili3,@gsm_num3,@e_mail3,@tlfn1,@tlfn2,@tlfn3,@tlfn4,@tlfn5)
END
vemedya.com
|
|
|
|
|
Now I don't have any clue but see my answer I have given for THIS[^], and try to give parameters value like that way.
And also show us a full error statement to be further analyzing.
|
|
|
|
|
hi again..i tried to add values like in the link u sent
at that time it given error like "an SqlParameter with parameter name '@firmanin_adi' is not contained by this SqlParameterCollection" in my process layer
vemedya.com
|
|
|
|
|
hi friend it adds the datas now i changed something more after u offered..thanks for help
and one more question; is it too redicilous way to write a method which gets 15 parameters in my process layer and them to call it in my form inside and to assign the parameters here ?
vemedya.com
|
|
|
|
|