Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Setting attached property
Message
From
04/07/2011 21:55:01
 
 
General information
Forum:
ASP.NET
Category:
Windows Presentation Foundation (WPF)
Environment versions
Environment:
C# 4.0
Miscellaneous
Thread ID:
01516846
Message ID:
01517273
Views:
40
>>>Hi,
>>>How to implement this:
private void SetAttachedProperty(FrameworkElement fe, string propertyName, object value)
>>>        {
>>>        }
when called, for example, with:
SetAttachedProperty(new TextBlock(), "Canvas.Left", 50);
>>>>>>>>
>>
>>I was watching this one to see if any one had an answer. So far no joy :-(
>>
>>Have you considered using XamlReader/Writer for this instead of rolling your own property setter?
>
>Hi (long time no 'speak')
>I don't think I can use that (but I might be missing something). Background:
>
>Say I have something like a TexBlock contained in a Canvas with various properties of the TextBlock set in XAML. At runtime the use can change the TextBlock properties by setting properties directly or by dragging/resizing etc.
>I need to track exactly only those properties have been changed and, in a future instantiation, apply those changes to the original TextBlock. I have code that captures the value of each property in a list when the layout is initially loaded. I get another list when the user wishes to save the changes and then compare the two lists to end up with a final List of just those properties which have changed. The list is a collection of:
[Serializable]
>    public class DependencyData
>    {
>        public DependencyData(string s, object o, Type t)
>        {
>            FieldName = s; FieldValue = o; OwnerType = t;
>        }
>        public string FieldName { get; set; }
>        public object FieldValue { get; set; }
>        //Not neccessary - added for debugging
>        public Type OwnerType { get; set; }
>      }
For normal dependency properties I can just use the 'else' approach:
Type atType = AT.GetType(); // AT is, say, the TextBlock
>            foreach (DependencyData d in changedProperties)
>            {
>                PropertyInfo pi = atType.GetProperty(d.FieldName);
>                if (pi == null)
>                {
>                            //Problem here if pi is an attached property
>                }
>                else
>                    pi.SetValue(AT, d.FieldValue, null);
>            }
>        }
At the moment in the (pi==null) I've resorted to the clunky:
string theClass = d.FieldName.Substring(0, d.FieldName.IndexOf('.'));
>                    string theProperty = d.FieldName.Substring(d.FieldName.IndexOf('.') + 1);
>                    switch (theClass)
>                    {
>                        case "Canvas":
>                            {
>                                switch (theProperty)
>                                {
>                                    case "Left":
>                                        {
>                                            Canvas.SetLeft(AT, (double)d.FieldValue);
>                                            break;
>                                        }
>                                     //etc
>                                    default:
>                                        {
>                                            throw new Exception(theProperty + " is unhandled Canvas");
>                                        }
>                                }
>                                break;
>                            }
>                        //etc
>                        default:
>                            {
>                                throw new Exception(theClass + "not handled for DependencyProperties");
>                            }
>                    }
but I really need a more generic, less exception prone approach :-{
>Any suggestions,
>Regards,
>Viv

************************************************

>Hi (long time no 'speak')
WPF Section here is pretty quiet. So I lurk.

Your solution was exactly what I was hoping to see if someone could avoid <g>

I'm really not a fan of massive switch statements when I can avoid them.

Since no one came up with a wonderful solution using reflection... Here's what I was thinking:

I have a quick and dirty utility I wrote that manages geometry in resource files and allows me to combine them into visuals. Similar to your scenario, it allows me to set properties on the objects. I haven't used it with attached properties, but in theory... that should work. What I do, is I read in the resource dictionary as XML. All the edits are done to the XML data. I display what I'm doing on screen by writing the XML to a memory stream and then I instantiate it using XamlReader.

Here's a snippit:
        XmlDocument doc = new XmlDocument();
        XmlNode node = doc.ImportNode(_Node.Clone(), true);
        node.Attributes.RemoveNamedItem("x:Key");
        doc.AppendChild(node);
        MemoryStream strm = new MemoryStream();
        doc.Save(strm);
        //FileStream fs = File.Create("test.xaml"); // For Testing
        //fs.Write(strm.ToArray(),0,(int)strm.Length);
        //fs.Close();
        strm.Position = 0;
        _Object = XamlReader.Load(strm);
Don't know if that idea will work for you, but I figured it was better than no idea. <g>
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform