WPF Application.DoEvents()

2010/09/25

VB6 or even .Net programmers know that in order not to block a desktop application UI when processing longer tasks, there is a little trick that can be applied, if the tasks contain a loop, which loop will allow a call to:
Application.DoEvents()
which will process Windows waiting messages.
But in WPF there is no such default method.
There are different approaches and implementations, but if you look for a fast solution, you can just add a reference to
System.Windows.Forms.dll
and the corresponding using directive and Application.DoEvents() is ready to use !
I usually use a directive with alias, in order not to conflict with other existing namespaces:
using SysWinForms = System.Windows.Forms;
So you can simply call:
SysWinForms.Application.DoEvents();


Using Reflection for retrieving values of static properties

2010/07/07

I had a list of classes for which I wanted to retrieve the static property Description; this is how I found out it can be done using Reflection:

Assembly assembly = Assembly.GetExecutingAssembly();
var types = assembly.GetTypes();
foreach (var type in types)
{
    if (!type.IsClass)
        continue;
    if (!type.IsSubclassOf(typeof(MyBaseClass)))
        continue;
    object obj = Activator.CreateInstance(type, new object[] { 0, 0 });
    PropertyInfo pi = obj.GetType().GetProperty("Description");
    string propValue = pi.GetValue(null, null).ToString();
}

Note:If Description is a property of the base class MyBaseClass, you’ll have to use obj.GetType().BaseType.GetProperty(“Description”); for this to work.
Also, as you can see, at least in my case, I need to create instances of the classes I work with, because Description property is defined in a base class, not in the derived ones, and the static property will be populated via constructors.


Searching files with LINQ

2009/11/10

LINQ is very powerful in many aspects of programming; for example, you can simulate the search for files feature of some known applications (Windows Explorer or Total Commander) with very few lines of code, as shown below:

    public List<FileInfo> SearchForFiles(String path, String ext, String search)
    {
        DirectoryInfo folder = new DirectoryInfo(path);
        return (from file in folder.GetFiles(ext, SearchOption.AllDirectories)
                where file.Name.ToLower().Contains(search.ToLower())
                orderby file.Name, file.Extension
                select file).ToList();
    }

Then, you can use in several ways the resulted list, for example by adding to your Windows Form application a DataGridView and setting its DataSource as following:

    dgvFiles.DataSource = SearchForFiles(path, extension, searchTerm).ToList();

Download a file in C#

2009/10/26

Easy task !
Import the System.Net namespace and after that use the DownloadFile method of the WebClient class:

public void DownloadFile(string link, string destination)
{
    using (WebClient webClient = new WebClient())
    {
        webClient.DownloadFile(link, destination);
    }
}

Navigate with C# WebBrowser control to a link and wait for full page loading

2009/10/26

If you need to build an application that is using the functionality of the WebBrowser control and want to wait until a page is loaded (somehow simulating the synchronous loading of a page), you can use the following piece of code:

private const int sleepTimeMiliseconds = 5;

public void NavigateAndWaitForLoad(WebBrowser wb, string link, int waitTime)
{
    wb.Navigate(link);
    int count = 0;
    while (wb.ReadyState != WebBrowserReadyState.Complete)
    {
        Thread.Sleep(sleepTimeMiliseconds);
        Application.DoEvents();
        count++;
        if (count > waitTime / sleepTimeMiliseconds)
            break;
    }
}


First peek on retrieving Entity Framework entities with Lambda expressions

2009/10/14

After adding an ADO.NET Entity Data Model item to the .Net project, you can easily retrieve a list of entities using Lambda expressions. Let’s suppose that the data model added to the project is called MyDataEntities and that it links to a table called Person, having Name as column. The following code can be used to retrieve the list:

    public static List<Person> GetPersons()
    {
        try
        {
            using (MyDataEntities context = new MyDataEntities())
            {
                return context.Person.OrderBy(p => p.Name).ToList<Person>();
            }
        }
        catch
        {
            // Do exception handling here
            throw;
        }
    }

Write to text file in C# using TextWriter

2009/10/07

Very simple:

    public static void WriteLog(String logFileName, String msg)
    {
        try
        {
            TextWriter writer = new StreamWriter(logFileName, true);
            writer.WriteLine(DateTime.Now.ToString("mm:ss") + " " + msg);
            writer.Flush();
            writer.Close();
            writer = null;
        }
        catch
        {
        }
    }

The second parameter of the StreamWriter constructor specifies if the text will be appended to the file; if set to false, the file will be overwritten.


Internalization in Java using ResourceBundle

2009/09/29

In order to implement localization in your Java application, you can use ResourceBundle and PropertyResourceBundle classes, as following:

Step 1: Create a method that receives a string key for which you need the “translation”:

public String getI18NString(String key) {
    if (key == null)
        return "[" + key + "]";;
    
    try {
        PropertyResourceBundle resBundle = (PropertyResourceBundle) ResourceBundle.getBundle("localization");
        return resBundle.getString(key);
    } catch (Exception e) {
    }
    
    return "[" + key + "]";
}

Step 2: Add localization files to your project, under a source folder. The default translations will be grouped under a file named like localization.properties, the additional languages will use files like localization_fr_FR.properties or localization_de_DE.properties:

01InternalizationInJavaLocalizationFiles

The content of such a file will be as following:

BTN_OK=Approuver
BTN_CANCEL=Annuler

Step 3: Test the implemented method:

@Test
public void testI18N() {
    assertEquals(getI18NString("BTN_CANCEL"), "Cancel");
    Locale.setDefault(new Locale("ro", "RO"));
    assertEquals(getI18NString("BTN_CANCEL"), "Anuleaza");
    Locale.setDefault(new Locale("fr", "FR"));
    assertEquals(getI18NString("BTN_CANCEL"), "Annuler");
}

Create XSD file with JAXB

2009/09/26

This post is a sequel of the two previous ones talking about serializing Java classes to XML through JAXB in Eclipse. So, it started when I wanted to serialize objects without using an XSD schema… and the only solution I found was by creating the ObjectFactory.java class that JAXB needs when going through marshalling process (check More on XML serialization with JAXB post).

Still, this solution was not good enough for me, I wanted to find a mechanism inside JAXB to do the task, not outside it, or by cheating… So I googled some more and found a way to generate an XML schema (XSD file) from Java classes; not what I was looking for, but interesting (and tricky) stuff. In order to do this, add to your Java project (described in previous 2 articles) the following method:

public void generateSchema(String suggestedSchemaName) throws Exception
{
    final File parentFolder = new File(".");
    final String schemaName = suggestedSchemaName;
        
    JAXBContext jc = JAXBContext.newInstance(Graph.class);
    jc.generateSchema(new SchemaOutputResolver() {
        @Override
        public Result createOutput(String namespace, String schema) throws IOException {
            return new StreamResult(new File(parentFolder, schemaName));
        }
    });
}

As you can see, JAXBContext class has the generateSchema method, which takes an instance of a SchemaOutputResolver class, that needs to override the createOutput method in order to output the XSD file. So you can afterwards call the method presented above as follow:

generateSchema(“graphXmlSchema.xsd”);

More on XML serialization with JAXB

2009/09/24

I posted some days ago an article explaining how to “XML-serialize” objects with JAXB in Eclipse. The downside of using XSD for XML serialization is the dependency on the XML schema that will generate java classes; this is because I wanted to extend the classes to have extra-functionality, more constructors and so on. So I started looking for a way to serialize objects to XML without creating XSD definitions… but I found a problem: every time java classes are generated, an additional class, called ObjectFactory.java is also created. It is also needed for XML marshalling/unmarshalling. The only viable solution I found was to write my one ObjectFactory.java class, to be used by JAXB when serializing objects.

Step 1: Create the java classes that you need. In my case, I had two main entities, Node and Line, and two additional collections, Lines and Nodes. I also created a Graph entity, holding a list with nodes and a list with lines. Below are presented Line.java, Lines.java and Graph.java files

Line.java

package drawgraph.objects;

import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Line", propOrder = { "startNode", "endNode" })
public class Line {

    @XmlAttribute(name = "StartNode")
    protected int startNode;
    @XmlAttribute(name = "EndNode")
    protected int endNode;

    public Line(int start, int end) {
        this.setStartNode(start);
        this.setEndNode(end);
    }
    
    public Line() {
        this(0, 0);
    }
    
    public int getStartNode() {
        return startNode;
    }

    public void setStartNode(int value) {
        this.startNode = value;
    }

    public int getEndNode() {
        return endNode;
    }

    public void setEndNode(int value) {
        this.endNode = value;
    }

}

Lines.java

package drawgraph.objects;

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "lines", propOrder = { "lines" })
public class Lines {

    @XmlElement(name = "Line")
    protected List<Line> lines;

    public List<Line> getLines() {
        if (lines == null) {
            lines = new ArrayList<Line>();
        }
        return this.lines;
    }
}

Graph.java

package drawgraph.objects;

import java.io.*;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.bind.annotation.*;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Graph")
public class Graph {

    @XmlElement(name = "Nodes", required = true)
    protected Nodes nodes = new Nodes();
    @XmlElement(name = "Lines", required = true)
    protected Lines lines = new Lines();
    @XmlAttribute(name = "StartNode")
    protected int startNode;
    @XmlAttribute(name = "EndNode")
    protected int endNode;
    
    public void addNode(int x, int y) {
        getNodes().add(new Node(x, y, getNodes().size() + 1));
    }

    public void addLine(int start, int end) {
        getLines().add(new Line(start, end));
    }
    
    public List<Node> getNodes() {
        return nodes.getNodes();
    }

    public void setNodes(Nodes value) {
        this.nodes = value;
    }

    public List<Line> getLines() {
        return lines.getLines();
    }

    public void setLines(Lines value) {
        this.lines = value;
    }

    public int getStartNode() {
        return startNode;
    }

    public void setStartNode(int value) {
        this.startNode = value;
    }

    public int getEndNode() {
        return endNode;
    }

    public void setEndNode(int value) {
        this.endNode = value;
    }
    
    public void marshalToFile(String fileName) {
        try {
            JAXBContext jc = JAXBContext.newInstance(this.getClass().getPackage().getName());
            Marshaller m = jc.createMarshaller();
            m.marshal( this, new FileOutputStream(fileName) );
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static Graph unmarshalFromFile(String fileName) {
        try {
            JAXBContext jc = JAXBContext.newInstance((new Graph()).getClass().getPackage().getName());
            Unmarshaller um = jc.createUnmarshaller();
            return (Graph) um.unmarshal(new File(fileName));
        } catch (Exception e) {
            return new Graph();
        }
    }
    

}

In order to be able to serialize the above classes, we must use the XML annotations like @XmlRootElement, @XmlElement, @XmlAttribute, @XmlType. For the serialization, we use the same JAXBContext, Marshaller and Unmarshaller classes.

Step 2: Implement the ObjectFactory.java class

package drawgraph.objects;

import javax.xml.bind.annotation.XmlRegistry;

@XmlRegistry
public class ObjectFactory {

    public ObjectFactory() {
    }

    public Graph createGraph() {
        return new Graph();
    }

    public Node createNode() {
        return new Node();
    }

    public Line createLine() {
        return new Line();
    }

}

As you can see, the class must be preceded by @XmlRegistry annotation.

Step 3: Test the serialization

package drawgraph.objects;

import org.junit.*;
import static org.junit.Assert.*;

public class GraphTest {

    Graph graph;
    
    @Test
    public void test_graph()
    {
        createGraph();
        graph.marshalToFile("newGraphOutput.xml");
        Graph secondGraph = Graph.unmarshalFromFile("newGraphOutput.xml");
        assertTrue(secondGraph.getLines().size() == 2);
        assertTrue(secondGraph.getNodes().size() == 3);
    }
    
    private void createGraph()
    {
        graph = new Graph();
        graph.addNode(60, 60);
        graph.addNode(110, 110);
        graph.addNode(60, 110);
        graph.addLine(1, 3);
        graph.addLine(2, 3);
    }
}

Step 4: Check the result

01MoreXmlJaxbFileOutput


Follow

Get every new post delivered to your Inbox.