|
Unless you create a new abstract class that derives from Control and implements the interface (stubbing out the interface methods as abstract methods), you can't automatically get what you want.
You say that you have to handle a wide variety of controls including TreeView, so you will be dealing with Controls that don't implement the interface, correct?
If this is the case, your method should do something like this:
public void MyFunction(Control control)
{
IMyNotificationsControl imnc = control as IMyNotificationsControl;
if (imnc != null)
{
}
}
I, for one, do not think the problem was that the band was down. I think that the problem may have been that there was a Stonehenge monument on the stage that was in danger of being crushed by a dwarf.
-David St. Hubbins
|
|
|
|
|
Thanks for the reply Kentamanos (and krisp). Both solutions are reasonable. I actually used krisps, since I had to fail if the control did not implement the interface. The discussion is really a theoretical one.
My point was that I couldn't just derive from Control and include the interface methods, since, for example, I'd need to handle controls derived from both (e.g.) ListView and TreeView. Since I can't insert my new control in the object hierarchy above these two controls, given the single inheritance nature of things in C# I couldn't see the kind of solution I'd really like, which is the ability to declare a Type consisting of a class plus an interface.
I guess there could be a restricted interface construct that would provide something more than what C# currently provides but that was less then full multiple interitance. This would be something like:
interface IMyInterface RestrictedTo <objecttype1>, <objecttype2>
Oh well...
Tom
|
|
|
|
|
Another solution could be to have interface with a method that returns Control
interface IMyIFace
{
... methods ...
Control GetControl();
}
that way, when you inherit from some control and implement IMyIFace, you will return this in GetControl() method.
Then in the methods that accepts IMyIFace, you can get a hold of control by calling GetControl(),
and you'll have guarantee that the passed object implements IMyIFace and that it can give you control.
Of course, then it's up to the implementator to make sure they return this in GetControl()
|
|
|
|
|
Anyone have any ideas on how to store richtext in an access database; then retreive the data and reload the richtext control without losing the formatting?
I've spent days looking on the web for answers and so far came up empty.
Any help will be greatly appreciated...
|
|
|
|
|
I've never done this, but what occurs to me is to turn the content of the control into a bunch of bytes and then write the content of the control into the database as a blob. Of course, there could be a simpler more direct route...
|
|
|
|
|
Just store it in a Memo field, and use the RichTextBox.Rtf property, which you could've found in seconds if you used the .NET Framework SDK documentation instead of days searching on the web.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hi Heath,
Your suggestion seemed to work. Thanks!. I used
s = txtData.Rtf.ToString ();
to save the data in a string and then
txtData.Rtf = s;
to put the data back in a richtext control.
In trying to move it to an MS Access memo control I used the following:
string x = @"UPDATE notes SET notetext = " +
'"' +
txtData.Rtf +
'"' +
" WHERE notekey = 1";
When I try to update the record I get a SQL error. I think the string is not getting moved properly in x. SQL gives me the following error:
Message = Syntax error in string in query expression '"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Trebuchet MS;}}
\viewkind4\uc1\pard\f0\fs24 TEST\par
}'.
I'm new to this so I'm feeling pretty dumb here. Any ideas on what I can do to make this work.
Thanks,
Bob
|
|
|
|
|
First of all, you don't need to use RichTextBox.Rtf.ToString - it already is a string.
Second, the error in your query expression is because you're not encoding the string. If you use parameterized queries, you'll find this is taken care of for you and is a much better design, especially when you have to do batch updates:
OleDbConnection conn = new OleDbConnection("your connection string");
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = "UPDATE notes SET notetext = @notetext WHERE notekey = 1";
OleDbParameter notetextParam = cmd.Parameters.Add("@notetext",
OleDbType.LongVarWChar, 4000);
try
{
notetextParam.Value = txtData.Rtf;
cmd.ExecuteNonQuery();
}
finally
{
if (conn != null && (conn.State & ConnectionState.Open) != 0)
conn.Close();
} With ADO.NET, do not use string concatentation to avoid problems like this. Using parameterized queries are far more robust and provide many other features like being able to use an OleDbCommandBuilder to create INSERT, UPDATE, and DELETE statements that correspond to a provided simple SELECT statement, and more.
Notice also that I did not include my parameter in quotes in the query string. ADO.NET will take care of this as well.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Heath,
Thanks a million. Your suggestions worked perfectly.
Bob
|
|
|
|
|
Just wondering,
Why, in a child class, can you not set an abstract method you override, to call a different method that returns something else, but has the same signature. And declare the abstract method by Explicit means.
I know it is a compile error, but is it not something they could have easily allowed, or are there behind the scenes issues im not understanding?
You can do this with interfaces, so why not abstract methods?
public class BaseClass
{
protected abstract string MyMethod();
}
public class ChildClass : BaseClass
{
private int _MyInt = 6;
protected override string BaseClass.MyMethod()
{
return _MyInt.ToString();
}
public int MyMethod()
{
return _MyInt;
}
}
|
|
|
|
|
Few comments...
Classes with abstract methods have to be marked abstract. Think about it. You can't instantiate one because it doesn't know how to implement the abstract method, so the class becomes abstract.
You can never define two functions with the same name that take the same parameters but return different types. This class would never compile (has nothing to do with abstract classes):
<div class="code" style="font-family:Courier New;font-size:10pt;background-color:#FFFFFF;">
<span style="color:#0000FF;">public class </span><span style="color:#000000;">test<br>
{<br>
</span><span style="color:#0000FF;">string </span><span style="color:#000000;">Fred()<br>
{<br>
</span><span style="color:#0000FF;">return </span><span style="color:#000000;">"one";<br>
}<br>
<br>
</span><span style="color:#0000FF;">int </span><span style="color:#000000;">Fred()<br>
{<br>
</span><span style="color:#0000FF;">return </span><span style="color:#000000;">1;<br>
}<br>
}<br>
</span>
</div>
You probably know, but the second class should look like this:
<div class="code" style="font-family:Courier New;font-size:10pt;background-color:#FFFFFF;">
<span style="color:#0000FF;">public class </span><span style="color:#000000;">ChildClass : BaseClass<br>
{<br>
</span><span style="color:#0000FF;">private int </span><span style="color:#000000;">_MyInt = 6;<br>
<br>
</span><span style="color:#0000FF;">protected override string </span><span style="color:#000000;">MyMethod()<br>
{<br>
</span><span style="color:#0000FF;">return </span><span style="color:#000000;">_MyInt.ToString();<br>
}<br>
} <br>
</span>
</div>
Is there something else I'm missing on this?
I, for one, do not think the problem was that the band was down. I think that the problem may have been that there was a Stonehenge monument on the stage that was in danger of being crushed by a dwarf.
-David St. Hubbins
|
|
|
|
|
I was getting at the fact that you can do this with interfaces, so why not abstract classes?
Seems like it should be logical, an abstract class is just like a regular class with the abstract methods comming from an interface, except it has the abstract keyword.
public interface BaseInterface
{
string MyMethod();
}
public class ChildClass : BaseInterface
{
private int _MyInt = 6;
string BaseInterface.MyMethod()
{
return MyMethod().ToString(); // this calls int MyMethod()
}
public int MyMethod()
{
return _MyInt;
}
}
|
|
|
|
|
I see what you're saying now.
In order for you to call the ChildClass's "version" of the method (not the one that he implements to fulfill his derivation from the abstract class), you'd have to have some sort of syntax for specifying which version you were calling.
In the case of the interfaces, it's really a function of casting to the inteface and calling the method. It doesn't make sense to cast an instance of the the derived class to the derived class to get the derived one's "personal" version.
I'm sure this syntactical stuff (which is fairly nasty) was purposely avoided. That's one good reason to not allow multiple inheritance (which is a design descision MS made with C#).
I, for one, do not think the problem was that the band was down. I think that the problem may have been that there was a Stonehenge monument on the stage that was in danger of being crushed by a dwarf.
-David St. Hubbins
|
|
|
|
|
Ok, well this is pretty much exactly what i want to do with an abstract method.
public class DataBase
{
...
}
public class BaseClass
{
protected abstract DataBase DoMethod();
}
public class DataChild : DataBase
{
...
}
public class ChildClass : BaseClass
{
private int _MyInt = 6;
protected override DataBase BaseClass.DoMethod()
{
return DoMethod();
}
public DataChild DoMethod()
{
return new DataChild();
}
}
I am returning an object in my child's method that derives from the object being returned in my base's method.
So, this would not have any problems that I can see.
I don't see how this has anything to do with multiple inheritance, because I would still only be inheriting from one class. There is no reason why the return value can't be derived from the abstract method's return type.
I can not see in any way this conflicting with any multiple inheritance, or anything.
That way when the object is casted to its base class, the proper return type is still received.
What am I missing for this not to work?
|
|
|
|
|
I only mention multiple inheritance because having syntax to specify exactly whose version of a function you're calling is something that you HAVE to have once your language implements multiple inheritance. There's many an interview question on C++ based upon this type of crap . If you only have single inheritance, you can call your parent's implementation with a keyword like "base".
One thing to realize is it doesn't matter if the methods return different types at all. Two functions can't have the same name and take the same parameters unless we can use a specific "vtable" to call each one.
That said, think about this:
namespace Test
{
public interface I
{
void MethodA();
}
public class C : I
{
void Test.I.MethodA()
{
}
public void MethodA()
{
}
}
}
Given this code, instantiate an instance of C and call the I interface version of MethodA without first casting C to an I. AFAIK, it can't be done.
So the mechanism we use to differentiate between which version we're calling is a cast to the specific class. Casting allows us to specify whose "vtable" (a table that points to functions) we want to use.
Now in the case of a derived class, you can't do something like:
DerivedClass d = new DerivedClass();
((DerivedClass)d).MethodA();
because casting something that's already a given class doesn't really do anything.
Casting something to a base class or an interface gives you the "vtable" of that class, which allows us to "specify" a particular method. The problem comes into the fact that the base class's vtable might have a pointer to the derived class in the case the method gets overridden. This is what happens to virtual functions that are redefined with an override. Abstract methods are automatically virtual, they just have no "default" implementation. You are required to supply one in the case of abstract methods.
If we can't use casting to "filter" our vtable and specify which method we're calling, we would need some other method of specifying. C++ ends up using the "::" operator to do this. If you want to call a specific parent class version, you just call it with something like:
ParentClass::MethodA()
It becomes a real mess...
Does any of this help at all? I'm probably not doing this discussion justice. Have you done any C++ in the past?
I, for one, do not think the problem was that the band was down. I think that the problem may have been that there was a Stonehenge monument on the stage that was in danger of being crushed by a dwarf.
-David St. Hubbins
|
|
|
|
|
Hello all,
I have create a Backup application, but for now I have a little problem. I can't copy a file who was already in use. It was a big problem for me, cause I never know when the file will be in use. What can I do to bypass this problem. To make my program I have use this function that I have found on code project:
public static void copyDirectory(string Src,string Dst)
{
String[] Files;
if(Dst[Dst.Length-1]!=Path.DirectorySeparatorChar)
Dst+=Path.DirectorySeparatorChar;
if(!Directory.Exists(Dst)) Directory.CreateDirectory(Dst);
Files=Directory.GetFileSystemEntries(Src);
foreach(string Element in Files)
{
// Sub directories
if(Directory.Exists(Element))
copyDirectory(Element,Dst+Path.GetFileName(Element));
// Files in directory
else
File.Copy(Element,Dst+Path.GetFileName(Element),true);
}
}
If somebody can help me it will be nice.
Demo
|
|
|
|
|
This is far too low-level for .NET. It requires direct file system access since Windows denies access to open file handles. Most backup software will skip open files (which is why many companies disconnect their servers during backups). Backup Exec has a separate module for open file handles and you have to pay quite highly for it. Hopefully you've got the idea that you can't just solve this by setting a flag somewhere.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thank you for your answer,
but is it possible to see the state of a file. I Means can I check if the file I want to copy was open, and if it is delayed my copy.
Thanks
Demo
|
|
|
|
|
Thank you for your answer,
but is it possible to see the state of a file. I Means can I check if the file I want to copy was open, and if it is delayed my copy.
Thanks
Demo
|
|
|
|
|
Well, an exception is being thrown, right? Use that to your advantage.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Does anyone know of an API for controlling the output of a surround sound eg. 5.1 system?
I want to be able to say: play this wave file through the left rear speaker only.
Thanks
-Matt
|
|
|
|
|
DirectX[^] - as an added bonus, 9.0 introduced managed assemblies for easy access for .NET languages.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yeah, I know. I tried using DirectSound under DirectX 9.0 but AFAIK you can't do what I want - localise a speaker.
The best you can do is set a sound source to be from an xyz position - but that won't localise a speaker.
-Matt
|
|
|
|
|
Hi there
Can anyone tell me how i can change the action of the
close button on the control box of the form.
i want to hide the form rather than to close it when
the close button is pressed.
VisionTec
|
|
|
|
|
Handle the Form.Closing event (or override the related method for derived classes), cancel it, and do something else:
public class MyForm : Form
{
protected override void OnClosing(CancelEventArgs e)
{
this.Hide();
e.Cancel = true;
base.OnClosing(e);
}
}
Microsoft MVP, Visual C#
My Articles
|
|
|
|