2009-12-29 2 views
4

Обновление: Это подтвержденная ошибка в бета-версии Silverlight 4. http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=523052Итерация над полями Word с использованием ComAutomationFactory в Silverlight 4

Я решил эту проблему, переключившись на полномасштабное приложение WPF и используя обычный старый Microsoft.Office.Interop.Word. Но мне все еще очень интересно, как заставить это работать, используя динамические значения из ComAutomationFactory.

Это может быть больше вопросов C# 4.0, но я пытаюсь использовать класс ComAutomationFactory в доверенном приложении SL4 для загрузки документа Word, изменения текста и его печати.

Используя регулярные окна приложения, это довольно легко:

Object oMissing = System.Reflection.Missing.Value; 
    Object oTrue = true; 
    Object oFalse = false; 

    Application oWord = new Application(); 
    Document oWordDoc = new Document(); 

    oWord.Visible = false; 

    object oTemplatePath = "C:\\Users\\jwest\\Desktop\\DocumentTemplate.dotx"; 
    oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); 

    foreach (Field myMergeField in oWordDoc.Fields) 

Однако в SL4 вы должны использовать динамический ключевое слово. Он отлично работает, пока я пытаюсь перебирать мои поля:

Object oMissing = System.Reflection.Missing.Value; 
    Object oTrue = true; 
    Object oFalse = false; 

    dynamic oWord = ComAutomationFactory.CreateObject("Word.Application"); 

    oWord.Visible = false; 

    object oTemplatePath = "C:\\Users\\jwest\\Desktop\\DocumentTemplate.dotx"; 
    dynamic oWordDoc = oWord.Documents.Add(ref oTemplatePath, ref oMissing, ref oMissing, ref oMissing); 
    dynamic fields = oWordDoc.Fields; 

    foreach (var myMergeField in fields) 

В этом случае я получаю сообщение об ошибке выполнения, говоря, что я не могу неявно преобразовать ComAutomationMetaObjectProvider в IEnumerable. Независимо от того, что я делаю, любые свойства, связанные с моим объектом Word com, имеют тип ComAutomationMetaObjectProvider, и я не могу их перебирать.

Было упомянуто, что я должен попытаться получить поле в виде строки из члена.

 for (int i = 0; i < oWordDoc.Fields.Count; i++) 
     { 
      String field = oWordDoc.Fields.Item[i].Result.Text; 
     } 

Это приводит к интересным исключением: HRESULT: 0x800A16E6, который когда Googled, не вызывает абсолютно ничего.

+0

Я не знаю ответ на ваш вопрос, но просто хотел бы отметить, что в C# 4, вы не должны» t нужны параметры 'ref oMissing'. – CoderDennis

ответ

6

Это, конечно же, не проблема с C# - VB.NET имеет ту же проблему. Существует либо ошибка здесь, либо что-то не документированное, но в любом случае представляется невозможным объявление объектов коллекции.

Существует другой способ, однако, это доступ к отдельным членам коллекции. Вот пример (в VB.NET), который позволяет вам проходить через Fields.Item. (здесь нет ошибки или закрытия Word, у моего .dotx есть два поля - 1) и 2) автор).

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click 
    Dim wrd As Object = ComAutomationFactory.CreateObject("Word.Application") 
    Dim path As String = "C:\Users\me\test.dotx" 
    Dim wordDoc As Object = wrd.Documents.Add(path) 
    Dim fieldsCount As Integer = wordDoc.Fields.Count 
    Dim fieldResults As String = Nothing 
    For i As Integer = 1 To fieldsCount 
     fieldResults = fieldResults & " " & wordDoc.Fields.Item(i).Result.Text & vbNewLine 
    Next 
    TextBox1.Text = "Field Results: " & fieldResults 
End Sub 
+0

Интересно, что вы упомянули об этом. Я попробовал то же самое, но в итоге получил другое сообщение об ошибке, нечто довольно общее. Я уточню вопрос. – James

+0

Если вы попытались установить wordDoc.Fields.Item (i) .Result.Text, используя «dynamic» в C# или Dim As Object в VB, вы получите ту же ошибку, о которой вы говорили выше. Измерение его как строки, хотя работает. Поэтому я мог бы также сказать Dim sixField как String = wordDoc.Fields.Item (6) .Result.Text. О, еще одна вещь - когда вы говорите: «Все отлично работает, пока я не попытаюсь перебрать мои поля», он фактически разбивается на «динамические поля = oWordDoc.Fields»; потому что это когда поля присваиваются типу ComAutomationMetaObjectProvider. Я пробовал такие вещи, как «Dim fields as Ienumerable (of Object)», но это тоже не удается. –

+0

Я все еще получаю исключение HRESULT: 0x800A16E6 при попытке получить к нему доступ через Fields.Item [i] .Result.Text.Конечно, я мог бы перевести свой VB на C#. Я обновил вопрос. – James

1

Может быть что-то связанное с внедрением Silverlight 4.0 в ComAutomationFactory. У меня нет VS2K10 Beta 2, поэтому я не могу проверить.

Использования «динамические» типов прекрасно работает в консольном приложении, хотя ...

dynamic oWord = //ComAutomationFactory.CreateObject("Word.Application"); 
    Activator.CreateInstance(Type.GetTypeFromProgID("Word.Application", true)); 

oWord.Visible = false; 

object oTemplatePath = "c:\\vishal.dotx"; 
dynamic oWordDoc = oWord.Documents.Add(ref oTemplatePath); 
dynamic fields = oWordDoc.Fields; 

Console.WriteLine("template has {0} merge flds", fields.Count); 

//Method 1 
Console.WriteLine(string.Join("\n", ((IEnumerable)oWordDoc.Fields).Cast<dynamic>().Select(x=>(string)x.Result.Text).ToArray())); 

//Method 2 
foreach (dynamic fld in fields) 
Console.WriteLine(fld.Result.Text); 
Смежные вопросы