Note that there are some explanatory texts on larger screens.

plurals
  1. POHow to use a static utility method for property setters in a utility class
    primarykey
    data
    text
    <p>I'm trying to achieve two-way binding between a DataGridView and a BindingList that provides data for the DGV. Some columns do not yet reflect changes in the underlying list and I think it's because I have not provided property setter(s) to notify of property changes. Rather than code the setter for the Rows property the same way I did for the Process property, I'm trying to get more "elegant" and I realize I am stuck....</p> <p>I stumbled upon a very interesting writeup for a more elegant approach and I'm trying to implement the concepts of it (please see): <a href="http://www.gavaghan.org/blog/2007/07/17/use-inotifypropertychanged-with-bindinglist/" rel="nofollow">http://www.gavaghan.org/blog/2007/07/17/use-inotifypropertychanged-with-bindinglist/</a> </p> <p>Here is the code from Mike's article I want to use (established as <strong>Utilities.cs</strong> in my CBMI.Common project):</p> <pre><code>using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; namespace CBMI.Common { public static class Utilities { public static bool Set&lt;T&gt;(object owner, string propName, ref T oldValue, T newValue, PropertyChangedEventHandler eventHandler) { // make sure the property name really exists if (owner.GetType().GetProperty(propName) == null) { throw new ArgumentException("No property named '" + propName + "' on " + owner.GetType().FullName); } if (!Equals(oldValue, newValue)) // we only raise an event if the value has changed { oldValue = newValue; if (eventHandler != null) { eventHandler(owner, new PropertyChangedEventArgs(propName)); } } return true; // Please NOTE: I had to add this statement to avoid compile error: // "not all code paths return a value". } } } </code></pre> <p>So, my <strong>FIRST QUESTION</strong> about this: The author did not have a <strong>return</strong> statement in his article and I added it which resolved the compiler error. I'm guessing the eventHandler executes and returns and that this was an author omission and this should return true as the method wants a bool return type. Is that correct assumption?</p> <p>My <strong>2nd QUESTION</strong> shows what a C# rookie I am when I try to use this helper method above. I have coded this class into a separate file called <strong>InputFileInfo.cs</strong> in the same project (and namespace) as the above:</p> <pre><code> using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; namespace CBMI.Common { public class InputFileInfo : INotifyPropertyChanged { private bool processThisFile; public bool Process { get { return processThisFile; } set { processThisFile = value; this.NotifyPropertyChanged("Process"); } } public string FileName { get; set; } private long rowsReturned; public long Rows { get { return rowsReturned; } set { Utilities.Set(this, "Rows", ref rowsReturned, value, PropertyChanged); } } public string Message { get; set; } // constructor public InputFileInfo(string fName) { Process = true; FileName = fName; Rows = 0; Message = String.Empty; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); } } } </code></pre> <p>The setter for the 2nd property in this class is where I try to use Mike's static method:</p> <pre><code>Utilities.Set(this, "Rows", ref rowsReturned, value, PropertyChanged); </code></pre> <p>If I remove Utilities.Set and just code it as follows:</p> <pre><code>Set(this, "Rows", ref rowsReturned, value, PropertyChanged); </code></pre> <p>..then I get the compiler complaining that <strong>"the name 'Set' does not exist in the current context"</strong>. </p> <p>I tried adding a <strong>using Utilities; directive</strong> but that did not fix the problem. </p> <p>Finally, I do not understand the parameters: ref T oldValue, T newValue<br> nor the parameter called <strong>value</strong> where the Set method is invoked.</p> <p>Can someone please help me over these multiple confusions about this code so I can use these more advanced ideas?</p> <p><strong>---- EDIT UPDATE ----</strong> Two good answers helped me get this working. The "2nd question" in the original post above remains a bit elusive. Added comments for each requesting a "best practice" on how to package this so I can use the simple invoking syntax as in Mike's original article. That is, I'm seeking to invoke "helper" static methods by the method name only. I want to understand how to invoke like:</p> <pre><code>set { Set(this, "Rows", ref rowsReturned, value, PropertyChanged); } </code></pre> <p>instead of having to code as:</p> <pre><code>set { Utilities.Set(this, "Rows", ref rowsReturned, value, PropertyChanged); } </code></pre> <p>I got this working by coding Utilities.Set but I guess the question morphs a bit into - <strong><em>"Where do I put static methods and how to call them so I don't have to "qualify" them with the classname?"</em></strong> I would like to understand how to package generally useful "utility" type methods that don't require an instance of an object. In this case, the static method is called Set but I'd like to be able to add other static methods such as:</p> <pre><code>public static int HelpfulMethodXXXX(string s, int num) </code></pre> <p>I have a separately compiled DLL (Vstudio project) containing only class file(s). Ultimately, I'd like to think I could use this class in other applications. </p> <p>Where is the best place to declare these sort of static methods such that they could be invoked as:</p> <pre><code>int i = HelpfulMethodXXXX("Sample", testNumber); </code></pre> <p>instead of:</p> <pre><code>int i = ContainingClassName.HelpfulMethodXXXX("Sample", testNumber); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload