Clone visual tree with binding
here a class for clonning visualtree inside with binding
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
public class Header : ContentControl, ICloneable { static Header() { EditorHelper.Register<BindingExpression, BindingConvertor>(); } public object Clone() { StringBuilder outstr = new StringBuilder(); //this code need for right XML fomating XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.OmitXmlDeclaration = true; XamlDesignerSerializationManager dsm = new XamlDesignerSerializationManager(XmlWriter.Create(outstr, settings)); //this string need for turning on expression saving mode dsm.XamlWriterMode = XamlWriterMode.Expression; XamlWriter.Save(this, dsm); // recreate from stringbuilder StringReader stringReader = new StringReader(outstr.ToString()); System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(stringReader); object newObj = System.Windows.Markup.XamlReader.Load(xmlReader); if(newObj is Header) { Header h = newObj as Header; h.DataContext = this.DataContext; } return newObj; } } static class EditorHelper { public static void Register<T, TC>() { Attribute[] attr = new Attribute[1]; TypeConverterAttribute vConv = new TypeConverterAttribute(typeof(TC)); attr[0] = vConv; TypeDescriptor.AddAttributes(typeof(T), attr); } } class BindingConvertor : ExpressionConverter { public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) { if (destinationType == typeof(MarkupExtension)) return true; else return false; } public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType) { if (destinationType == typeof(MarkupExtension)) { BindingExpression bindingExpression = value as BindingExpression; if (bindingExpression == null) throw new Exception(); return bindingExpression.ParentBinding; } return base.ConvertTo(context, culture, value, destinationType); } } |
and use like this
1 2 3 4 5 6 7 8 |
<local:Header> <StackPanel Orientation="Horizontal"> <Ellipse Height="16" Width="16" Fill="Red" /> <TextBlock Text="{Binding Nom}" /> </StackPanel> </local:Header> |
Principes
- create a binding converter
- register converter for binding
- save xaml with settings and reload it
- set the same datacontext for source and clonning object
you must check if the datacontext of Header object is the real DataContext of object inside in visual tree
Categories: Non classé
Commentaires récents