c# - Dependency property of Custom Templated Control won't be set if it is set to binding in WinRT -
i wrote custom templated richtextblock in order represent emojis , links images , hyperlink buttons respectivly. has 1 "text" dependency property because conversion works process inside control when recieve plain text/string.
the problem if text property specific string text="asdasdsa", control represent "asdasdas" properly. if property set bind text="{binding something}", control won't work , setter text dependency property never fire.
the style of control this
<style targettype="local:myrichtextblock" > <setter property="template"> <setter.value> <controltemplate targettype="local:myrichtextblock"> <border horizontalalignment="center" width="auto" height="auto"> <stackpanel> <richtextblock x:name="childrichtextblock"/> </stackpanel> </border> </controltemplate> </setter.value> </setter> </style>
basically, converts plain text , replace emojis , hyperlinks in xaml, @ end add block of xaml code richtextblock paragraph.
the code of control
public sealed class myrichtextblock : control { richtextblock _richtextblock; stringbuilder builder = new stringbuilder(); regex urlrx = new regex(@"(?<url>(http:[/][/]|www.)([a-z]|[a-z]|[0-9]|[/.]|[~])*)", regexoptions.ignorecase); public myrichtextblock() { this.defaultstylekey = typeof(myrichtextblock); foreach (var key in emojidict.keys) { builder.append(key.replace("[", @"\[").replace("]", @"\]")); builder.append("|"); } builder.remove(builder.length - 1, 1); } private readonly dictionary<string, string> emojidict = new dictionary<string, string> { //dictionary of emojis key }; protected override void onapplytemplate() { _richtextblock = gettemplatechild("childrichtextblock") richtextblock; setrichtextblock(text); } public string text { { return (string)getvalue(textproperty); } set { setvalue(textproperty, value); } //this setter won't fire } // using dependencyproperty backing store text. enables animation, styling, binding, etc... public static readonly dependencyproperty textproperty = dependencyproperty.register("text", typeof(string), typeof(myrichtextblock), new propertymetadata("")); //conversion work, not related property think private void setrichtextblock(string value) { string abc = value; matchcollection matches = urlrx.matches(value); var r = new regex(builder.tostring()); var mc = r.matches(value); foreach (match m in mc) { value = value.replace(m.value, string.format(@"<inlineuicontainer><border><image source=""ms-appx:///assets/emoji/{0}.png"" margin=""2,0,2,0"" width=""30"" height=""30""/></border></inlineuicontainer>", emojidict[m.value])); } foreach (match match in matches) { string url = match.groups["url"].value; value = value.replace(url, string.format("<inlineuicontainer><border><hyperlinkbutton margin=\"0,0,0,-4\" padding=\"0,2,0,0\" navigateuri =\"{0}\"><stackpanel horizontalalignment=\"center\" height=\"25\" width=\"90\" background=\"#ffb8e9ff\" orientation = \"horizontal\"><image margin=\"5,0,0,0\" source = \"/assets/link.png\" width = \"15\" height = \"15\"/><textblock margin=\"4,2.5,0,0\" text=\"网页链接\" foreground=\"white\" fontfamily=\"microsoft yahei ui\" fontsize=\"14\" fontweight=\"bold\"/></stackpanel ></hyperlinkbutton></border></inlineuicontainer>", url)); } value = value.replace("\r\n", "<linebreak/>"); var xaml = string.format(@"<paragraph xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""> <paragraph.inlines> <run></run> {0} </paragraph.inlines> </paragraph>", value); var p = (paragraph)xamlreader.load(xaml); _richtextblock.blocks.add(p); } }
and way how use control
<datatemplate x:name="normaltemplate"> <grid grid.column="1" grid.row="1" d:layoutoverrides="leftmargin, rightmargin, topmargin, bottommargin" margin="0,15,0,15" name="normaltemplategrid"> //codes omit// <local:myrichtextblock x:name="weibotexttextblock" margin="20,35,0,0" text="{binding text}" grid.column="2" grid.row="1" d:layoutoverrides="horizontalalignment, topmargin, bottommargin, leftposition, rightposition, topposition, bottomposition" horizontalalignment="left" fontfamily="microsoft yahei"/> </grid> </datatemplate>
any ideas problem , solution this?
the setter there sake of completing dependency property. need define property changed callback text
property, -
public static readonly dependencyproperty textproperty = dependencyproperty.register(nameof(text), typeof(string), typeof(myrichtextblock), new propertymetadata("", ontextchange)); private static void ontextchange(dependencyobject d, dependencypropertychangedeventargs e) { var rtb = (myrichtextblock)d; rtb.setrichtextblock(e.newvalue.tostring()); }
Comments
Post a Comment