2009-10-02 7 views
3

J'ai une application Silverlight qui permet à l'utilisateur de dessiner dessus et de sauvegarder le dessin.Silverlight 3: convertir la collection de traits XML en une collection de stroboscopes?

La strokecollection dans le canevas est convertie en attributs xml et stockée dans la base de données. Le seul problème que j'ai maintenant est de convertir le xml en une collection de traits.

mes coups sont stockés en tant que tel:

<Strokes>  
    <Stroke>  
    <Color A="255" R="0" G="0" B="0" />  
    <OutlineColor A="0" R="0" G="0" B="0" />  
    <Points> 
    <Point X="60" Y="57" PressureFactor="0.5" />   
    <Point X="332" Y="52" PressureFactor="0.5" />  
    </Points>  
    <Width>3</Width>  
    <Height>3</Height>  
    </Stroke> 
</Strokes> 
+0

+1 Pour un puzzle intéressant, hmm ... – AnthonyWJones

Répondre

0

Voici votre code fortement factorisé: -

private StrokeCollection CreateStrokeCollection(string XMLStrokes) 
{ 
    XElement xmlElem; 
    try 
    { 
    return CreateStrokeCollect(XElement.Parse(XMLStrokes).Root); 
    } 
    catch (XmlException ex) 
    { 
    return new StrokeCollection(); 
    } 
} 

private StrokeCollection CreateStrokeCollection(XElement elem) 
{ 
    StrokeCollection result= new StrokeCollection(); 
    foreach (XElement elem in xmlElement.Elements("Stroke")) 
    { 
    result.Add(CreateStroke(elem)); 
    } 
    return result; 
} 


private Stroke CreateStroke(XElement elem) 
{ 
    var result = new Stroke(); 
    result.DrawingAttributes = CreateAttributes(elem); 
    result.StylusPoints.Add(CreatePointCollection(elem.Element("Points")); 
    return result; 
} 

private StylusPointCollection CreatePointCollection(XElement elem) 
{ 
    var result = new StylusPointCollection(); 
    foreach (XElment pointElem in elem.Elements("Point")) 
    { 
    result.Add(CreateStylusPoint(pointElem)); 
    } 
    return result; 
} 

private StylusPoint CreateStylusPoint(XElement elem) 
{ 
    double x = Convert.ToDouble(point.Attribute("X").Value); 
    double y = Convert.ToDouble(point.Attribute("Y").Value); 
    return new StylusPoint(x, y); 
} 

private DrawingAttributes CreateAttributes(XElement elem) 
{ 
    var result = new DrawingAttributes(); 
    result.Color = CreateColor(elem.Element("Color")); 
    result.OutlineColor = CreateColor(elem.Element("OutlineColor")); 
    result.Width = Convert.ToInt32(elem.Element("Width").Value); 
    result.Height = Convert.ToInt32(elem.Element("Height").Value); 
    return result ; 
} 

private Color CreateColor(XElement elem) 
{ 
    byte colorA = Convert.ToByte(color.Attribute("A").Value); 
    byte colorR = Convert.ToByte(color.Attribute("R").Value); 
    byte colorG = Convert.ToByte(color.Attribute("G").Value); 
    byte colorB = Convert.ToByte(color.Attribute("B").Value); 

    return Color.FromArgb(colorA, colorR, colorG, colorB);  
} 
0

Voici ma solution ... il semble que je pensais qu'il était trop confus avant que je ne me suis assis et regardé:

private StrokeCollection CreateStrokeCollectionfromXML(string XMLStrokes) 
    { 
     XElement xmlElem; 
     try 
     { 
      xmlElem = XElement.Parse(XMLStrokes); 
     } 
     catch (XmlException ex) 
     { 
      return new StrokeCollection(); 
     } 
     StrokeCollection objStrokes = new StrokeCollection(); 
     //Query the XML to extract the Strokes 
     var strokes = from s in xmlElem.Descendants("Stroke") select s; 
     foreach (XElement strokeNodeElement in strokes) 
     { 
      var color = (from c in strokeNodeElement.Descendants("Color") 
         select c).FirstOrDefault(); 
      DrawingAttributes attributes = new DrawingAttributes(); 

      byte colorA = Convert.ToByte(color.Attribute("A").Value); 
      byte colorR = Convert.ToByte(color.Attribute("R").Value); 
      byte colorG = Convert.ToByte(color.Attribute("G").Value); 
      byte colorB = Convert.ToByte(color.Attribute("B").Value); 

      attributes.Color = Color.FromArgb(colorA, colorR, colorG, colorB); 

      var outlineColor = (from oc in strokeNodeElement.Descendants("OutlineColor") 
           select oc).FirstOrDefault(); 

      byte outlineColorA = Convert.ToByte(outlineColor.Attribute("A").Value); 
      byte outlineColorR = Convert.ToByte(outlineColor.Attribute("R").Value); 
      byte outlineColorG = Convert.ToByte(outlineColor.Attribute("G").Value); 
      byte outlineColorB = Convert.ToByte(outlineColor.Attribute("B").Value); 

      attributes.OutlineColor = Color.FromArgb(outlineColorA, outlineColorR, outlineColorG, outlineColorB); 

      attributes.Width = Convert.ToInt32(strokeNodeElement.Descendants("Width").FirstOrDefault().Value); 
      attributes.Height = Convert.ToInt32(strokeNodeElement.Descendants("Height").FirstOrDefault().Value); 

      var points = from p in strokeNodeElement.Descendants("Point") 
         select p; 
      StylusPointCollection pointData = new System.Windows.Input.StylusPointCollection(); 

      foreach (XElement point in points) 
      { 
       double Xvalue = Convert.ToDouble(point.Attribute("X").Value); 
       double Yvalue = Convert.ToDouble(point.Attribute("Y").Value); 
       pointData.Add(new StylusPoint(Xvalue, Yvalue)); 
      } 

      Stroke newstroke = new Stroke(); 
      newstroke.DrawingAttributes = attributes; 
      newstroke.StylusPoints.Add(pointData); 
      //add the new stroke to the StrokeCollection 
      objStrokes.Add(newstroke); 
     } 
     return objStrokes; 
    } 
+0

C'est une bonne entrée pour 10. Cependant, je pense qu'il serait prudent de supposer que les éléments de contour ne contiennent pas eux-mêmes d'éléments de contour. Utilisez donc des éléments au lieu des descendants. – AnthonyWJones

+0

Facteur dans une fonction la création d'une couleur à partir d'un élément. – AnthonyWJones

+0

Pourquoi ne pas simplement utiliser 'var color = strokeNodeElement.Element (" Color ")' à la place de tout ce matériel inutile de LINQ. – AnthonyWJones

Questions connexes