I have field string in struct,
and i want learn real-time changed this field.
struct example {
public string ex;
}
examp = new example();<BR>
examp.ex = "test";
////// then program work and eamp.ex = "bing";
I need method
on_ex_changed()
{
if examp.ex changed then .....
}
online and simple plz
You can put an event at the setter as follows.
The event will be fired every time the setter is called.
public class MyObj
{
private RectangleF mRectangle;
public event EventHandler RectangleChanged;
public RectangleF Rectangle
{
get
{
return mRectangle;
}
set
{
mRectangle = value;
OnRectangleChanged();
}
}
protected virtual void OnRectangleChanged()
{
if (RectangleChanged != null)
{
RectangleChanged(this, EventArgs.Empty);
}
}
}
Related
I'm trying to create an event handler, that when some button is tapped on Content Dialog, the main Page or the Page that has called the Content Dialog receive the event.
I have found some examples about it in Stackoverflow as in other forums, but the one I'm using to get what I've told is this one. I'm having some problemas to create the event raiser and because it's my first time trying to do something like that I'm a bit lost on the implementation.
This is my code:
someClass.cs
public class updatedDB
{
public enum updateType
{
Delete, Update, None
}
private updateType _updateType;
private bool _isUpdated;
private int _ID;
private bool IsUpdated
{
get { return _isUpdated; }
set
{
_isUpdated = value;
ValueChanged?.Invoke(value);
}
}
public void NotifyUpdate(int ID, updateType UpdateType)
{
if (UpdateType == updateType.None)
return;
else
{
IsUpdated = true;
_ID = ID;
_updateType = UpdateType;
}
}
public updateType GetUpdateType()
{
return _updateType;
}
public int GetUpdatedID()
{
return _ID;
}
public event ValueChangedEventHandler ValueChanged;
}
public delegate void ValueChangedEventHandler(bool value);
And this is the event handler in another .cs file (Page.cs):
public Page()
{
this.InitializeComponent();
HardwareButtons.BackPressed += HardwareButtons_BackPressed;
UpdateEvent.ValueChanged += UpdateSpots;
}
private ValueChangedEventHandler UpdateSpots(bool value)
{
ValueChangedEventHandler handler = new ValueChangedEventHandler(value);
return handler;
}
Currently I have two part of this code underlined in red and I don't know how to correct them:
UpdateEvent.ValueChanged += **UpdateSpots**;
UpdateSpots is giving me "has an incorrect type of value " (translated to english from my VS GUI language).
And,
ValueChangedEventHandler handler = new ValueChangedEventHandler(**value**);
value is giving me "waiting name of method" error.
Thank you in advance.
I use C# and I want to trigger an event from within a class :
So if the Price property of a class was changed then an event onPriceChanged (outside the class) should be fired.
However, I get an error:
The name 'onPriceChanged' does not exist in the current context
How could I fix this?
(I guess that I could pass the eventhandler to the class via constructor...but if possible I would prefer not to pass the eventhandler to the class)
Here is my code :
using System;
public delegate void delEventHandler();
class clsItem
{
//private static event delEventHandler _show;
private delEventHandler _show;
private int _price;
public clsItem() //Konstruktor
{
_show += new delEventHandler(Program.onPriceChanged); // error here : The name 'onPriceChanged' does not exist in the current context
}
public int Price
{
set
{
_price = value;
_show.Invoke(); //trigger Event when Price was changed
}
}
}
class Program
{
static void Main()
{
clsItem myItem = new clsItem();
myItem.Price = 123; //this should trigger Event "onPriceChanged"
}
//EventHandler
public static void onPriceChanged()
{
Console.WriteLine("Price was changed");
}
}
You're doing this the wrong way round - you're trying to attach the event handler from the class, and clearly that cannot have access to the Program.onPriceChanged method!
You should expose your event, and attach the event handler from the client code (Program).
class clsItem
{
//private static event delEventHandler _show;
private delEventHandler _show;
private int _price;
public clsItem() //Konstruktor
{
}
public event delEventHandler Show
{
add { _show += value; }
remove { _show -= value; }
}
public int Price
{
set
{
_price = value;
_show?.Invoke(); //trigger Event when Price was changed
}
}
}
And:
clsItem myItem = new clsItem();
myItem.Show += onPriceChanged;
myItem.Price = 123; //this now does trigger Event "onPriceChanged"
Live example: http://rextester.com/WMCQQ40264
The way you're dealing with events is not a good practice. the reason why we use Events is to decouple the objects we create from the methods they need to call.
For example if you want to create another object of the same type(clsItem) and get it to call another method once its price changed, you get into trouble. So I'd suggest this code rather than the current one:
using System;
public delegate void delEventHandler();
class clsItem
{
public event delEventHandler PriceChanged;
private int _price;
public clsItem() //Konstruktor
{
}
public int Price
{
set {
if(value!=_price) // Only trigger if the price is changed
{
_price = value;
if(PriceChanged!=null) // Only run if the event is handled
{
PriceChanged();
}
}
}
}
}
class Program
{
static void Main()
{
clsItem myItem = new clsItem();
myItem.PriceChanged += new delEventHandler(onPriceChanged);
myItem.Price = 123; //this should trigger Event "PriceChanged" and call the onPriceChanged method
}
//EventHandler
public static void onPriceChanged()
{
Console.WriteLine("Price was changed");
}
}
Here is the more traditional way of doing what you want:
public delegate void delEventHandler();
class clsItem
{
public event delEventHandler Show;
private int _price;
public clsItem() //Konstruktor
{
}
public int Price
{
set
{
_price = value;
Show?.Invoke(); //trigger Event when Price was changed
}
}
}
class Program
{
static void Main()
{
clsItem myItem = new clsItem();
myItem.Show += onPriceChanged;
myItem.Price = 123; //this should trigger Event "onPriceChanged"
}
//EventHandler
public static void onPriceChanged()
{
Console.WriteLine("Price was changed");
}
}
Notice that clsItem no longer knows who is subscribing to its event. All it cares about is notifying any listeners who happens to be subscribed. There is no longer a dependency between clsItem and the onPriceChanged method.
I have a C# WPF application built with Visual Studio 2015. I'm using MVVM and the Observer Pattern.
My Provider is a user control called 'ucClientFilter1ViewModel' that contains two text box controls where the user can search for a client(s):
namespace NSUCClientControls
{
public class ucClientFilter1ViewModel : ViewModelBase, IObservable<ClientFilterParameter>
{
private string filterLocation;
private string whereSearch1;
private string whereSearch2;
private List<IObserver<ClientFilterParameter>> observers;
public ucClientFilter1ViewModel()
{
observers = new List<IObserver<ClientFilterParameter>>();
}
public string FilterLocation
{
get { return filterLocation; }
set { filterLocation = value; }
}
public string WhereSearch1
{
get { return whereSearch1; }
set
{
whereSearch1 = value;
TestUpdateGrid(filterLocation);
}
}
public string WhereSearch2
{
get { return whereSearch2; }
set
{
whereSearch2 = value;
TestUpdateGrid(filterLocation);
}
}
private void TestUpdateGrid(string _filterLocation)
{
var filterInfo = new ClientFilterParameter(this);
foreach (var observer in observers)
{
observer.OnNext(filterInfo);
}
}
public IDisposable Subscribe(IObserver<ClientFilterParameter> observer)
{
// Check whether observer is already registered. If not, add it
if (!observers.Contains(observer))
{
observers.Add(observer);
// Provide observer with existing data
var filterInfo = new ClientFilterParameter(this);
observer.OnNext(filterInfo);
}
return new Unsubscriber<ClientFilterParameter>(observers, observer);
}
internal class Unsubscriber<ClientFilterParameter> : IDisposable
{
private IObserver<ClientFilterParameter> observer;
private List<IObserver<ClientFilterParameter>> observers;
public Unsubscriber(List<IObserver<ClientFilterParameter>> _observers, IObserver<ClientFilterParameter> _observer)
{
observers = _observers;
observer = _observer;
}
public void Dispose()
{
if (observers.Contains(observer))
{
observers.Remove(observer);
}
}
}
}
}
My Observer is a user control called 'ucClientGrid1ViewModel' that contains a datagrid where the search results are displayed.
namespace NSUCClientControls
{
public class ucClientGrid1ViewModel : ViewModelBase, IObserver<ClientFilterParameter>
{
private IDisposable cancellation;
private ObservableCollection<Client> clientsMultiple;
public ucClientGrid1ViewModel()
{
}
public ObservableCollection<Client> ClientsMultiple
{
get
{
var myClientDataAccess = new ClientDataAccess();
clientsMultiple = myClientDataAccess.GetClientListFromSQL_Test2();
return clientsMultiple;
}
set
{
}
}
public virtual void Subscribe(ucClientFilter1ViewModel provider)
{
cancellation = provider.Subscribe(this);
}
public void OnNext(ClientFilterParameter myFilter)
{
OnPropertyChanged("ClientsMultiple");
var myDummyWindow = new dummyWindow();
myDummyWindow.Show();
myDummyWindow.Close();
}
public void OnError(Exception error)
{
throw new NotImplementedException();
}
public void OnCompleted()
{
throw new NotImplementedException();
}
}
}
This all works and I get the search results that I am expecting. But what I don't understand is why the inclusion of the following lines actually speed things up!
var myDummyWindow = new dummyWindow();
myDummyWindow.Show();
myDummyWindow.Close();
I'm new to MVVM and the observer pattern, so as I was writing the code I had included message boxes at various points to help me to follow the flow of it. It was all working as expected. Then I removed the message boxes and it still worked but the application was pausing at the end before you could continue to keep searching.
Putting a message box back in at the end prevented this pause. Replacing the message box with a "DummyWindow" that just opens and closes has the same affect and prevents the pause at the end. This is what I currently have but I'd rather not leave this in there.
Presumably opening the window causes something else to happen which stops some redundant process, and this then prevents the pause? What else could I do to prevent the pause at the end, without using this DummyWindow?
I've tried searching on here and with Bing with no luck.
Thanks in advance!
Edit:
ViewModelBase...
namespace NSCommon
{
public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable
{
protected ViewModelBase()
{
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
var e = new PropertyChangedEventArgs(propertyName);
handler(this, e);
}
}
public void Dispose()
{
OnDispose();
}
protected virtual void OnDispose()
{
}
}
}
ClientFilterParameter...
namespace NSCommon
{
public class ClientFilterParameter
{
public ClientFilterParameter(ucClientFilter1ViewModel myFilter)
{
FilterLocation = myFilter.FilterLocation;
WhereSearch1 = myFilter.WhereSearch1;
WhereSearch2 = myFilter.WhereSearch2;
}
private string filterLocation;
private string whereSearch1;
private string whereSearch2;
public string FilterLocation
{
get { return filterLocation; }
set { filterLocation = value; }
}
public string WhereSearch1
{
get { return whereSearch1; }
set { whereSearch1 = value; }
}
public string WhereSearch2
{
get { return whereSearch2; }
set { whereSearch2 = value; }
}
}
}
i'm trying to implement INotifyPropertyChanged within singelton class.
Here is my code:
public class plc : INotifyPropertyChanged
{
private static plc instance;
public plc()
{
}
public static plc Instance
{
get
{
if (instance == null)
{
instance = new plc();
}
return instance;
}
set
{
instance = value;
}
}
private static string _plcIp{get; set;}
public string plcIp
{
get
{
return _plcIp;
OnPropertyChanged();
}
set
{
_plcIp = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
I'm getting error unreachable code deleted and of course NotifyPropertyChange isn't working
It's because you are calling OnPropertyChanged(); after you return _plcIp;.
It should be called after you set the value. i.e.:
public string plcIp
{
get
{
return _plcIp;
}
set
{
if (value != _plcIp)
{
_plcIp = value;
OnPropertyChanged();
}
}
}
You should also check that the value is actually changing in the setter before raising the event.
There are several issues in your code:
if you are implementing singleton, then constructor of class should be private
use fields instead of private properties
properties should not be static (you are using singleton)
verify if property value really changed before raising OnPropertyChanged event
raise event before returning property value
use PascalNames for class name and properties names
raise event from setter instead of getter
Code:
public class Plc : INotifyPropertyChanged {
private static Plc _instance;
private Plc() { } // constructor should be private
public static Plc Instance
{
get
{
if (_instance == null)
_instance = new Plc();
return _instance;
} // you don't need setter
}
private string _plcIp; // instance field instead of static property
public string PlcIp
{
get { return _plcIp; }
set
{
if (_plcIp == value)
return; // check if value changed
_plcIp = value; // change value
OnPropertyChanged(); // raise event
}
}
// ...
}
This contains the error :
public string plcIp
{
get
{
return _plcIp;
OnPropertyChanged(); //This row..
}
set { _plcIp = value; }
}
It's in the Set method you want the update in the UI, not when you get the value.
Something like this :
public string plcIp
{
get { return _plcIp; }
set { _plcIp = value; OnPropertyChanged(); }
}
I have made a Base Form which is inherited by most Forms in the application. Base form contains a Status Bar Control that displays user name which is internally a static string. User can Switch User at any point in the application by pressing a button on status bar. At this point the user name in the status bar should also change, as if now it only changes in code and UI has no idea about the change. I have googled around and found that i need to bind the label with that static string by implementing a INotifyProperty Interface. I have implemented many example code without success.
Appreciate any help
use BindableAttribute for the property you want to bind a control to it.
[Bindable(true)]
public int Username {
get {
// Insert code here.
return 0;
}
set {
// Insert code here.
}
}
You must implement a class to notify prop changed and therefore the prop can not be static. Combine with a singleton pattern and you have yout solution.
public class Global : INotifyPropertyChanged
{
private string _userName;
public string UserName
{
get
{
return this._userName;
}
set
{
if (this._userName == value)
{
return;
}
this._userName = value;
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs("UserName"));
}
{
}
public event PropertyChangedEventHandler PropertyChanged;
private Global() {}
public static readonly Global Get = new Global();
}
Usage:
var currUserName = Global.Get.UserName;
Global.Get.PropertyChanged += (s, e) => Console.WriteLine(e.PropertyName);
Global.Get.UserName = "John";
And bind to Global.Get to property UserName.
I would:
1- Add a timer to the base form to update the status bar. (the timer resolution is uo to your requirement).
the timer Tick handler would be something like this:
private void timerStatusUpdate_Tick(object sender, EventArgs e)
{
toolStripStatusLabelMessage.Text = StatusMessage();
}
2 - Add a virtual StatusMessage method to your base class:
class BaseForm : Form
{
.......
public virtual string StatusMessage()
{
return "override me!";
}
}
3- override StatusMessage in all your derived classes
class XXXForm : BaseForm
{
........
public override string StatusMessage()
{
return "XXXForm status message";
}
}
I use Reactive Extensions for these things
For example if you have a Context class with a property UserName
you could do this
public static class Context
{
public static Subject<string> UserChanged = new Subject<string>();
private static string user;
public static string User
{
get { return user; }
set
{
if (user != value)
{
user = value;
UserChanged.OnNext(user);
}
}
}
}
And then on your forms just do
Context.UserChanged.ObserveOn(SynchronizationContext.Current)
.Subscribe(user => label.Text = user);
The ObserveOn(SynchronizationContext.Current) makes it safe for cross thread operation calls