Copying Font properties from one inline element to other

Hi,

I am working on inserting inline nodes into a paragraph.
I would like to apply the font properties from previous inline element to the node which i am inserting.

When I try to copy all the public properties via reflection, properties are SET in the object but after saving the document, node font is reset to default i think.

Could you please provide me with some insight how to copy Font properties from one inline node to another?

Code:

Document _wordDocument = new Document(@"D://1.docx");

NodeCollection collection = _wordDocument.GetChildNodes(NodeType.Run, true);
Run run = new Run(_wordDocument, "2BOLD OR NOT BOLD2");
SetFont(typeof(Font), ((Run) collection[0]).Font, run.Font);
collection[0].ParentNode.InsertAfter(run, collection[0]);
_wordDocument.Save(@"D://1.docx");

public static void SetFont(Type type, Font source, Font destination)
{
    FieldInfo[] myObjectFields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);

    foreach(FieldInfo fi in myObjectFields)
    fi.SetValue(destination, fi.GetValue(source));
}

Also I’ve attached the file.

Hi Oleh,
Thanks for your request. Please try using the following code:

public static void SetFont(Type type, Aspose.Words.Font source, Aspose.Words.Font destination)
{
    PropertyInfo[] myObjectProperties = type.GetProperties();
    foreach(PropertyInfo pi in myObjectProperties)
    {
        if (pi.CanWrite)
            pi.SetValue(destination, pi.GetValue(source, null), null);
    }
}

Best regards,

Hi I tried your method, but I receive

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.ArgumentException: Cannot return user defined styles by style identifier.
at Aspose.Words.StyleCollection.xf21e14e2c9db279a(StyleIdentifier xa3be2ccad541ab25, Boolean x988fcf605f8efa7e)
at Aspose.Words.StyleCollection.x590d8ef356786501(StyleIdentifier xa3be2ccad541ab25)
at Aspose.Words.Font.set_StyleIdentifier(StyleIdentifier value)
— End of inner exception stack trace —
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.SetValue(Object obj, Object value, Object[] index)

Maybe there is other non-reflection way how to copy font properties ?

Hi Oleh,
Thanks for your inquiry.
I think you can just clone the previous inline node and change the text of the cloned node. This will retain formatting of the original node.
Thanks,

Hi,

I tried that but in some cases it still throw an exception.
I don’t like reflection approach so I decided to find other way how to implement that.

I tried to use DocumentBuilder class, and use Write method for emitting the text.
It works great for inserting text before node, but when i try to emit text after node it use wrong formatting.

I am using following code:

public override void EmitTextAfter(string text)
{
    Node lastNode = TrailingNode ?? Node; <--Trailing node means CommentRangeEnd, Node means Comment
    DocumentBuilder.MoveTo(lastNode);
    DocumentBuilder.Write(text);
}

public override void EmitTextBefore(string text)
{
    Node firstNode = LeadingNode ?? Node; <--Leading node means CommentRangeStart
    DocumentBuilder.MoveTo(firstNode);
    DocumentBuilder.Write(text);
}

Is there any way to pop font from document builder by moving to the first node and apply that to the method which emits text after?

Just to be clear, i will describe my issue.
I have a word document with different formatting. In this document there are comments, form fields and a lot of text. I need to remove all comments and form fields and before and after deleted fields I need to insert text.
I’ve already implement logic that inserts text and removes those fields.

Currently my problem is the formatting of the nodes I insert.
In MS word you can simply do the following:

comment.range.insertafter or insertbefore

Could you please provide me with some insight how to insert text, so the font, position and behaviour would be the same as with automation?

Currently with document builder approach, i have correct formatting for inserting before and after formfields and before commentrange start, but when i insert after commentrangeend I got some default(Maybe aspose formatting the font name is really strange there) formatting.

Hi Oleh,
Thanks for your inquiry.
The technique you are using is the best way to about what you are trying to achieve.
Regarding the issue with font being lost when the document builder is positioned at a CommentRangeEnd node, I managed to reproduce the issue on my side. We will keep you informed of any developments regarding a fix for this.
In the mean time you can just move the builder to the previous node using the code below and this issue should disappear.

builder.MoveTo(commentEnd.PreviousSibling);

Thanks,

I will try it today and post results, however seems i tried that yesterday.

Could you please also add a ticket regarding creating method that apply/copy font from one element to another? This is quite common task, and it would great to have that functionality, currently in .Net i assume it can be somehow done via reflection(But i think it is last workaround that should be considered, because it is additional overhead that could be avoided and there could be exceptions), but i didn’t have time to work on that. However in other languages, for example Java, i don’t know if there is such functionality like reflection. I think that functionality will be nice feature for community.

Thanks,
–Oleh

Hi Oleh,
Thanks for your request. Sure, we will consider this. But I think in your case it would be easier to use Styles or just clone the node from which you would like to inherit formatting, change its content and insert right after the original node.
Best regards,

aske012:
Hi Oleh,
Thanks for your inquiry.
The technique you are using is the best way to about what you are trying to achieve.
Regarding the issue with font being lost when the document builder is positioned at a CommentRangeEnd node, I managed to reproduce the issue on my side. We will keep you informed of any developments regarding a fix for this.
In the mean time you can just move the builder to the previous node using the code below and this issue should disappear.
builder.MoveTo(commentEnd.PreviousSibling);
Thanks,

Hi,

Could you please provide me with information if that ticket was fixed?

Kind regards,
–Oleh

Hi Oleh,
Thanks for your request. Unfortunately, the issue is still unresolved. We will let you know once it is fixed.
Best regards,

Hi Oleh,

Thanks for your patience.

I took a closer look into this issue with a few more tests and I’ve seen the behavior we observed is not actaully a bug. It appears most likely that the CommentRangeEnd node simply is not formatted in the same way that the runs before it. This would account for the difference in font.

The most simple solution is to make sure the formatting in such situations is carried over to all of the comment nodes i.e highlight the entire paragraph and apply font and character formatting.

If you think this is still incorrect, please attach your document here to the forums which demonstrates the issue and I will double check it for you.

Thanks,

The issues you have found earlier (filed as WORDSNET-4665) have been fixed in this .NET update and this Java update.

This message was posted using Notification2Forum from Downloads module by aspose.notifier.