|
The Scripting.Dictionary has nothing to do with the .NET FCL, so it doesn't implement IDictionary . It is an RCW (Runtime Callable Wrapper) to a COM object and you must use the COM methods and properties it exposes. The typelib importer (tlbimp.exe) does, however, provide the GetEnumerator which enumerates over the keys, but this is only defined by the DictionaryClass (though Keys() would as well since it's actually an object[] array that you could cast to IEnumerable ).
Take a look at this example code:
using System;
using Interop.Scripting;
public class Test
{
static void Main()
{
IDictionary dict = new DictionaryClass();
Add(dict, "a", 1);
Add(dict, "b", 2);
Add(dict, "c", 3);
object[] keys = (object[])dict.Keys();
for (int i=0; i<keys.Length; i++)
{
object key = keys[i];
object value = dict.get_Item(ref key);
Console.WriteLine("{0}: {1}", key, value);
}
object a = "a";
Console.WriteLine("\na={0}", dict.get_Item(ref a));
}
static void Add(IDictionary dict, object key, object value)
{
dict.Add(ref key, ref value);
}
} The only reason I don't use a foreach loop (uses the IEnumerable implementation) is because the key variable would be read-only, which you can't use with a ref , which is required to call get_Item .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Wow ! Thanks for the quick and very clear reply. You've helped me understand my problem thanks. I just have one quick (and rather silly) question for you. Where can I find the Interop.Scripting assembly ? I can't seem to find it anywhere on my system. I've done a websearch and found a file called "Interop.Scripting.dll" and I managed to add it in to my projects. However when I try to reference it the compiler complains that it can't see it. What am I doing wrong ?
-Pete
|
|
|
|
|
It's the namespace of the interop assembly. I generated the interop assembly using:
tlbimp.exe /out:Interop.Scripting.dll scrrun.dll Chances are that you already have it since you were asking about it. VS.NET creates these automatically when you reference a COM server. If that's not the namespace it generated (though it should be), just change it to whatever is appropriate.
Also note that IDictionary here is Interop.Scripting.IDictionary, Interop.Scripting , not System.Collections.IDictionary, mscorlib . If you have both namespaces imported in your source file, you either need to change the scripting IDictionary to DictionaryClass , fully qualify the type, or use an alias like:
using IDict = Interop.Scripting.IDictionary; Then use IDict instead of IDictionary .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Yep that worked. Thanks a million Heath. I really appreciate all your help. However I have one more quick question. I was looking at your code and you seem to have methods that my version of Interop.Scripting does not. You have a get_Item() method in your DictionaryClass while I don't. I only have the following methods:
Add()
Equals()
Exists()
get_HashVal()
GetEnumerator()
GetHashCode()
GetType()
Items()
Keys()
let_Item
Remove()
RemoveAll()
set_Key()
ToString()
Does this mean I have a different version then you ?
|
|
|
|
|
If you're using IntelliSense, you won't see it. It's defined in the assembly, however. You can't use the Item property because C# can not "call" a property that takes parameters, except for the indexer (which Item is not).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Wow ! Thanks Heath. I owe you one; a BIG one. Thank you so much for all your help. You've made my day !
|
|
|
|
|
Hi!
Being given:
- a Source.doc file
- a variable myRange containg a Range (in the matter fact a paragraph taken from the Source file); this paragraph can contain pictures, not only plain text
- an empty Target.rtf file,
my problem is:
How can I paste the whole content of myRange into the Target file? (...because I want it saved in rtf format)
Should I use the Word Selection object or the Clipboard or what else? How?
Thanx!
--Miha
|
|
|
|
|
You would need to use the Selection object, yes. This can give you a Range which you can use or replace. I would suggest looking at the object model documentation in MSDN Online[^]., though you'll probably get better help if you have installed the developer help files with Office. The stuff on MSDN doesn't contain a very good TOC (table of contents) for the object model documentation. The developer help files (can be installed with any version of Office, IIRC) will be much more help.
Keep in mind that while those examples typically use VB (a COM client language), the same applies for you since you've created an (or are using an existing) interop assembly that wraps the COM objects, enums, and members (a Runtime Callable Wrapper, or RCW). While parameters may typically be declared as object or ref object , you still pass in the right objects (or a reference to them using ref someObjectInstance ) according to what the object model documentation says.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Hello,
Using C# on a web form with a textbox for the user to enter a word and then click on a button to have the word entered into a listbox. After the user has entered as many words as they wish they can then click on another button to have all of the words in the listbox processed.
My question is: how do I retreive the words from the listbox?
I would think I could loop through the listbox and get each word but I am not finding anything like this in my searches.
For (int i = 0; i < Listbox1.Count; i = i+1)
{
wordlist[i] = Listbox1.?????;
//processing code here
}
Can someone aim me in the right direction?
Regards,
Bill Antonacchio
|
|
|
|
|
for(int i=0; i<listBox1.Items.Count; i++)
{
wordlist[i] = listBox1.Items[i];
}
#include "witty_sig.h"
|
|
|
|
|
Thank you, I guess. When I try to use this code there are several things that come up in the Build Error list in VS.NET.
Doesn't there need to be a condition and an iteratr in the For statement. Also, Property or indexer 'string.this[int]' cannot be assigned to -- it is read only AND Cannot implicitly convert type 'System.Web.UI.WebControls.ListItem' to 'char' appear in the Build Error list.
Can you give me a little more detail?
This help is very much appreciated.
|
|
|
|
|
I think you want ListBox1.Items[i].Text
|
|
|
|
|
Thank you tried it and that works!
Bill
|
|
|
|
|
Hi guys,
We have a C# Windows application, now user ask if we can enlarge the font size through the whole application. I wonder how should we accomplish it?
And one more, if we do so, do we end up massing around the layout?
Thanks,
|
|
|
|
|
You can recursively loop through the .Controls of the form (and all controls that are children of other controls) and set the .Font property of each. Should be easy.
This won't mess up the layout of the application (i.e. your buttons won't move) however, if the text is large enough some of it obviously won't be visible.
#include "witty_sig.h"
|
|
|
|
|
|
I'm getting to the point where I feel comfortable with remoting, but I've ran into a problem that has caused me to question my original design. Hopefully you guys can shed some light on this.
I need my server application to talk to all connected clients. Additionally, I need the clients to be able to talk to the server (i.e. 2 way communication here). I have a single MarshalByRef class called Messenger, used by both client and server, that does the talking and listening.
The way it worked was I had my server publish his Messenger instance (using RemotingServices.Marshal method). Any client who wanted to connect to the server would simply connect (using RemotingServices.Connect method) to the server's Messenger instance, then call theServerMessenger.Login method. This all works fine and dandy.
The problem is that the server needs to talk to the connected clients. I can use the above algorith (i.e. the client .Marshal his Messenger instance and have the server call methods on that), but in order for that to work, calling RemotingServices.Connect on that instance requires an IP address obviously, meaning this solution will work only for LANs. If the server was on a machine outside the network, this solution would fail because the clients don't have IP addresses visible outside the network.
Another thought I had was that the client could pass his Messenger object to the server when he connects. That seems to work until the server tries to call a method on that client's Messenger object, the server tells me an internal server error occurs.
So there is my problem. I'd appreciate any thoughts on this.
#include "witty_sig.h"
|
|
|
|
|
The clients really just need to provide an object which the server communicates (like callbacks). This, of course, has to be a remotable object, but you don't need to worry about connecting back to the client so long as you are using a channel that supports 2-way communication, like the TcpChannel . By the very nature of HTTP, this won't work (although there are elaborate ways to simulate 2-way communication using polling, and IIRC there's one on CodeProject).
Just find a decent .NET Remoting chat example. There's plenty available on the 'net and probably a few here on CodeProject as well. It's a pretty simple concept where the server stores the client object and communicates with it. Using sponsors and lifetime management effectively (see ILease and ISponsor interface documentation in the .NET Framework SDK), you could even remove clients from an internal IList (or whatever you want to use) when they disconnect (of course always do error-checking and remove the client in case they're not connected and their sponsor has not yet timed out).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
So you're saying basically to use a TcpChannel. I've been doing this, and whenever the server tries to communicate with the client objct, the server throws an internal error.
However, this is only the case when the server is running outside the LAN, and the client running inside the LAN. So it appears to be a firewall issue, perhaps the ports are being blocked.
#include "witty_sig.h"
|
|
|
|
|
More than likely a firewall is the problem. Proxies can also be a problem, as we're dealing with right now (mostly certain makes of proxies).
If the client and/or server is NAT'd (Network Address Translation) - not just simply firewalled (since a firewall can protect a network of non-reserved IP address) - you definitely have a problem that you can't get around at all or easily. To be honest, that often stumps me.
Take MSN and Windows Messengers for example. They require that your firewall (and the other end, if necessary) uses UPnP to publish the external IP address. The firewall will still route traffic accordingly, but the server and/or client does need to know the firewall's address. This is one possible fix. You can find more information about UPnP on MSDN (I've worked with it a little, but probably won't be able to help you with that).
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Ok that figures thanks. One more question
If the server is inside the LAN, clients outside the firewall could still access the server provided I've setup port forwarding on the firewall, right?
For instance, if the server is running on 10.10.10.10, and I've setup my firewall to forward traffic on port 4030 to 10.10.10.10, then code the following:
const string ipAddressOfFirewall = ...;
const int port = 4030;
RemotingServices.Connect(typeof(ILogin), string.Format("{0}:{1}/Login.rem", ipAddressOfFirewall, port);
This seems feasible, but I'd be shocked if it works. Is it possible?
#include "witty_sig.h"
|
|
|
|
|
Good question. I guess that depends on how the server is bound. If it uses a hostname as opposed to an IP address, it should work. Give it a try and let us know.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Much to my suprise, this actually worked. :yay: The initial server-to-client manipulation seems much slower (need to run more tests to be certain about that), but yeah, it actually works.
#include "witty_sig.h"
|
|
|
|
|
I want to insert a row in a table which has a PK in the first field. I make a INSERT and give parameters to the sql server for all fields except the id field which is set in the db as Autoincrement so i dont have to worry about.
ALL of this is working fine.
But now i want to work immediatly after the insert with the new id of this row, which was given to the row automaticly by the sql-server. My problem now is that i have no Idea how to get the id value into my code (sure I can make a select query questioning all the parameters which i still have from the insertcommand, and ask for the id but this way seems very complicated to me!!!)
So if any more experienced Programmer than me can help me, please!!!
10000 Thanks in advanced.
PS
Languages C#, ADO.Net, and Sql Server 2000
best regards helli
|
|
|
|
|
Typically, you add a SELECT statement after your INSERT statement when used with a SqlDataAdapter (fills a DataSet from a SQL Server database using Fill , or vice versa using Update ). This makes sure that your DataSet is filled with what SQL Server assigned to the PK field.
To include both an INSERT and SELECT, separate your statements with a semi-colon (;):
sqlDataAdapter1.InsertCommand = new SqlCommand(
"INSERT INTO MyTable Name VALUES (@Name); SELECT ID, Name FROM MyTable",
sqlConnection1);
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|