Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Help! Get Resource Reference in Windows Application at Design Time
 

Help! Get Resource Reference in Windows Application at Design Time

I am developing a custom control for my windows form application.

This control has a property named �/span> Bytes �/span> , which get the bytes from a file stored in resX File

In windows form application, the file reference in resX File is typed as bytes. So I just use that type as this property type.

For loading the file with less code, I just want to design a custom UITypeEditor for this property. I hope it would be running like the ImageEditor that the VisualStudio Default Used. When you select a project resource value, the code in Form.Designer.cs will like �/span> global::[ProjectName ].Properties.Resources.[ResourceName ] �/span> .

I use EnvDTE to get the project resX file path, and then use the ResXResourceReader to get the resource value I want. But the code in Form.Designer.cs is �/span> new bytes { byte )(31)),((byte )(11)), �/span> } �/span> . It is the value of resource, not the reference. It means I would refresh the property by hand for each control, when the resource update.

It �/span> s terrible! Could someone save me?

ebread  Sunday, June 28, 2009 7:59 AM
use CodeDomSerializer
http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx
It control the code being serialize to the file.
Experience
Myexp  Friday, July 03, 2009 1:42 AM
You will need to override the ImageEditor class. That's not an easy job. google won't help you because no document or sample has been made.
Myexp  Tuesday, June 30, 2009 6:49 AM
Yes, there is no sample been made.(I have searched it for a week).

I am sure it is not an easy job. I just want to know how to make the the Visual Studio Wirte the words like �/span> global::[ProjectName ].Properties.Resources.[ResourceName ] �in the file.

ebread  Wednesday, July 01, 2009 1:04 PM
Can somebody help me?
ebread  Thursday, July 02, 2009 10:34 AM
use CodeDomSerializer
http://msdn.microsoft.com/en-us/library/system.componentmodel.design.serialization.codedomserializer.aspx
It control the code being serialize to the file.
Experience
Myexp  Friday, July 03, 2009 1:42 AM
Thanks, I will try it tomorrow. It's night in my area now.
ebread  Friday, July 03, 2009 2:46 PM
I have try it. It work well.

But there is another question, Which way should I use to pass the seleced resource name( the name selected in a custom UITypeEditor) to the custom serializer.

I used a static class to store the name, it work well on only one custom control in the form. When there are two, they may use the same resource name. I mean the seconed setting operation erase the first.

I think I should store the control name at the same time. but I can't find a way to get it.

What shoud I do? Use EnvDTE OR Compnent.Design?
ebread  Tuesday, July 07, 2009 9:12 AM
using System;
using System.Collections;
using System.Collections.Generic;
using System.CodeDom;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
using System.Drawing;
using System.Windows.Forms;


namespace ReportControl
{
    internal class ReportSerializer : CodeDomSerializer
    {

        public override object Deserialize(IDesignerSerializationManager manager, object codeObject)
        {
            // This is how we associate the component with the serializer.
            CodeDomSerializer baseClassSerializer = (CodeDomSerializer)manager.
            GetSerializer(typeof(ReportControl).BaseType, typeof(CodeDomSerializer));

            /* This is the simplest case, in which the class just calls the base class
                to do the work. */
            return baseClassSerializer.Deserialize(manager, codeObject);
        }

        public override object Serialize(IDesignerSerializationManager manager, object value)
        {
            /* Associate the component with the serializer in the same manner as with
                Deserialize */
            CodeDomSerializer baseClassSerializer = (CodeDomSerializer)manager.
                GetSerializer(typeof(ReportControl).BaseType, typeof(CodeDomSerializer));

            object codeObject = baseClassSerializer.Serialize(manager, value);

            /* Anything could be in the codeObject.  This sample operates on a
                CodeStatementCollection. */
            if (codeObject is CodeStatementCollection)
            {
                CodeStatementCollection statements = (CodeStatementCollection)codeObject;

                string ControlName = GetControlName(statements);
                SetBytesPropertyValue(ControlName, statements);
               

            }
            return codeObject;
        }

        /// <summary>
        /// Get the control Name
        /// </summary>
        /// <param name="statements"></param>
        /// <returns></returns>
        string GetControlName(CodeStatementCollection statements)
        {
            foreach (CodeStatement dom in statements)
            {
                CodeAssignStatement assDom = dom as CodeAssignStatement;
                if (assDom != null)
                {

                    CodePropertyReferenceExpression prop = assDom.Left as CodePropertyReferenceExpression;

                    if (prop != null && prop.PropertyName == "Name")
                    {
                        CodePrimitiveExpression value = assDom.Right as CodePrimitiveExpression;

                        return (string)value.Value;
                    }

                }


            }//foreach

            return string.Empty;
        }


        /// <summary>
        /// Set 
        /// </summary>
        /// <param name="statements"></param>
        void SetBytesPropertyValue(string ControlName, CodeStatementCollection statements)
        {
            //Get cache content
            string ProjectName = ReportCache.GetProjectName(ControlName);
            string ResourceName = ReportCache.GetResourceName(ControlName);

            //If cache is null, return
            if (ProjectName == string.Empty || ResourceName == string.Empty)
                return;

 
            foreach (CodeStatement dom in statements)
            {
                if (dom is CodeAssignStatement)
                {
                    CodeAssignStatement assDom = (CodeAssignStatement)dom;

                    if (assDom.Left is CodePropertyReferenceExpression)
                    {
                        CodePropertyReferenceExpression prop = (CodePropertyReferenceExpression)assDom.Left;

                        if (prop.PropertyName == "Bytes")
                        {

                            MessageBox.Show(assDom.ToString());

                            string expression = String.Format("global::{0}.Properties.Resources.{1}", ProjectName, ResourceName);

                           ////There Set The Code I Want
                           assDom.Right = new CodeSnippetExpression(expression);

                        }

                    }

                }


            }//foreach
        }

    }
}

ebread  Tuesday, July 07, 2009 9:19 AM

You can use google to search for other answers

Custom Search

More Threads

• How do I abort or cancel a Text Box input.
• How to add Backgroung Image of panel at particuler position
• Custom Controls with C#
• VS 2008 error HRESULT 0x80042929
• Get the designer for a control
• Paiting user control at design-time not correctly working [Using OnPaintAdornments()]
• Designer won't accept custom ToolBoxItem on drag drop
• Visual Studio 2005 MaskedTextBox
• Having two controls focused at the same time
• Doing undo & redo operations....