0

I apologize in advance for a noob question. I have a string which is changing without my control (another party's string) lets call it firstString, every time this string changes I need to carry out an action in my program.

so I made a class that implements the "INotifyPropertyChanged" Interface, and created a string in it with a property, lets call it secondString, and on the main method of the form I've created a "PropertyChangedEventHandler" and an event method which shows a message box with the value of firstString.

everything works well if I manually test and change firstString by clicking a button to change its value and I get a message box with firstString's value after it went through secondString's Property, I set it like this: SecondString(this is a property) = firstString;

but the thing is firstString is changing by itself, and I don't have control over it, so if it is set by code to equal secondString's property what happens is that it only works for the first time that it runs.

so now every time secondString's property is changing, the event fires and that part is working OK. but I need to set secondString's value with firstString's value automatically every time that firstString's value changes. and I kind of figure that INotifyPropertyChanged should have somehow worked here for this part as well but I can't understand how. so I was trying to figure our how to "bind" string's A value to secondString's property, and got into DataBinding, but I couldn't find any example to bind two strings together, only about binding to or from a control.

EDIT: here is a code to demo, I think the key that I've missed to note is that firstString is a string I get by another party's class library.

Using AnotherPartyLibrary;

FirstClass fc;          

 public Form1()
        {
            InitializeComponent();

            fc = new FirstClass();
            fc.PropertyChanged += new PropertyChangedEventHandler(fc_PropertyChanged);

            fc.SecondString = AnotherPartyLibrary.firstString;

            this.Disposed += new EventHandler(Form1_Disposed);
        }

     void fc_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
           MessageBox.Show("Something changed!" + e.PropertyName);
        }

    public class firstClass :INotifyPropertyChanged
    {
        private string secondString = string.Empty;

        public string SecondString
        {
            get { return this.secondString; }
            set
            {
                this.secondString = value;
                NotifyPropertyChanged("SecondString");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

How is this problem is usually solved? Many Thanks in advance!

Edit: can anybody offer another solution other than what a.azemia has offered?Thanks again!

Ray.

Ray
  • 407
  • 1
  • 3
  • 15
  • If you could post some code, it would help.. – Abhishek Jan 23 '15 at 05:17
  • Can you provide sample source code of what you are doing? – a.azemia Jan 23 '15 at 05:20
  • How is firstString getting updated? Where does this happen and how are you getting its value? You need to call Notify when this happens, but it's difficult to advise you on exactly how without knowing more details. Please include a simple example of what you are doing and what you want to happen. – Esoteric Screen Name Jan 23 '15 at 05:23
  • I understand that you want to be notified when the `firstString` changes. So why are you implementing the `INotifyPropertyChanged` event on the `secondString`?You should implement the `INotifyPropertyChanged` on the `firstString` and then you should do whatever it is that you want to in the event. You have written that you want to perform an action when the `firstString` changes. I am writing this comment based on that. Post some sample code. – Abhishek Jan 23 '15 at 05:23
  • Does the first string live in a control? And edit field? Does that control update when the string changes? – i_am_jorf Jan 23 '15 at 05:27
  • Thanks for your comments, let me just mention that I don't have access to firstString where it is created, it is on only get by using another class library that I can get this string's value. I've added a code to demo. – Ray Jan 23 '15 at 06:19
  • So to clarify `AnotherPartyLibrary` isn't your implementation, Code that updates value of `firstSring` is out of your control ie `AnotherPartyLibrary` could initially update `firstString`? `AnotherPartyLibrary` or `firstString` doesn't emit any change event via its api? – Chris Moutray Jan 23 '15 at 06:32
  • ... perhaps it would help if you specify what the 3rd part component is? – Chris Moutray Jan 23 '15 at 06:32
  • @ChrisMoutray exactly as you said. there is no event related to the change of this string, it's something I need to do with it which wasn't expected probably, `AnotherPartyLibrary` **is** constantly updating `firstString`. it's another company's class library (.dll) with an API, I don't think it would help to know which one exactly is it. this is certainly my situation which I need to workaround.. Thanks for the help.. – Ray Jan 23 '15 at 06:46
  • Assuming you have *no* control over `firstString`, then the given solution is your best bet. – BradleyDotNET Jan 23 '15 at 21:17
  • Microsoft Task Parallel Library (TPL) is a bit complex but was built exactly for this type of situation. https://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx – phillip Jan 23 '15 at 21:20
  • Thanks BradleyDotNET for your opinion, and thanks @phillip for your direction, this is the comment I was waiting for. I'll look into it and post my thoughts here. – Ray Jan 24 '15 at 01:00

1 Answers1

4

Based on the assumption that you do not have control over firstString then you can use BackgroundWorker to monitor firstString value and update SecondString

        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += (s, e) =>
            {
                while (true)
                {
                    if (!fc.SecondString.Equals(AnotherPartyLibrary.firstString))
                    {
                        fc.SecondString = AnotherPartyLibrary.firstString;
                    }
                    Thread.Sleep(1000);
                }
            };
        bw.RunWorkerAsync();

You can also use Microsoft TPL to achieve the same result

public async void YourMethodName() 
{
    await Task.Run(() => 
        {
                while (true)
                {
                    if (!fc.SecondString.Equals(AnotherPartyLibrary.firstString))
                    {
                        fc.SecondString = AnotherPartyLibrary.firstString;
                    }
                    Thread.Sleep(1000);
                }
        });
}

However, if you can update the code for firstString then you should implement INotifyPropertyChanged on firstString.

a.azemia
  • 304
  • 1
  • 6
  • Thanks, I can't update the code where firstString is created or get to firstString's class. I can only get it as it is. this string will sometimes be updated a few times a second so I don't think that it could "Thread.Sleep" for a full second, other than that I am not sure how BackgroundWorker would work, I think I need to test it, and I am not sure about it but isn't using BackgroundWorker a little "resource heavy"? thanks again. I wonder if there are any other more designated solutions. – Ray Jan 23 '15 at 06:22
  • The resource usage will not be noticeable in your case. You can also increase the amount of time Thread will sleep if needed. – a.azemia Jan 23 '15 at 06:37
  • Thanks, I can't let it sleep at all, I need to know the value of firstString at every second.. – Ray Jan 23 '15 at 06:40
  • Thanks @a.azemia! your solution does work for me. the only thing that I am concerned about is whether there is a more designated way to accomplish the same task (if not, I'll mark your answer as the answer) and if your solution is really not heavy on resources as you say. many many thanks again! – Ray Jan 23 '15 at 15:48
  • @Ray. If you find a more designated way to accomplish this please do share. You can also use TPL as commented by Phillip introduced in .NET4 which also involves running asynchronous operations. – a.azemia Jan 24 '15 at 20:16
  • sure @a.azemia I am trying to find out how to carry this out with TPL right now, as of now I've read in numerous places that Task.Run is a preferable way to do this. take a look at this post for example: [link]http://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-round-1.html and here: [link]http://stackoverflow.com/questions/3513432/task-parallel-library-replacement-for-backgroundworker I am trying to write a code that will use Task.Run but there is not a lot of simple examples of how to do this. I'll keep you updated. – Ray Jan 25 '15 at 04:01
  • I didn't figure out how to do this. I need help and I am thinking about posting a new question. how to implement Task.Run in an async way, just like your BackgroundWorker solution. there are not enough examples of this on the web! – Ray Jan 26 '15 at 21:54
  • I've posted a question on how to accomplish this with TPL here: http://stackoverflow.com/questions/28103426/how-to-know-when-a-string-changed-and-do-something Thanks for your help, if Backgroundworker will be a better solution for me eventually I'll mark your answer as the answer. Thanks again! – Ray Jan 26 '15 at 22:35