c# - Custom Indicator Control -
control (c# code):
public partial class redgreenstatusindicator : usercontrol, inotifypropertychanged { public redgreenstatusindicator() { this.initializecomponent(); dependencypropertydescriptor dpd = dependencypropertydescriptor.fromproperty (archiverdetails.ardetailsproperty, typeof(archiverdetails)); dpd.addvaluechanged(this, delegate { this.objectvaluechanged(); }); status = false; } void redgreenstatusindicator_loaded(object sender, routedeventargs e) { } public bool status { { return (bool)getvalue(statusproperty); } set { bool old_value = status; setvalue(statusproperty, value); if ((old_value == true) && (status == false)) { hide_green(); show_red(); } if((old_value == false) && (status == true)) { hide_red(); show_green(); } } } private void show_green() { if (greeninterior.opacity == 0) run_storyboard("show_green_indicator"); } private void hide_green() { if (greeninterior.opacity != 0) run_storyboard("hide_green_indicator"); } private void show_red() { if (redinterior.opacity == 0) run_storyboard("show_red_indicator"); } private void hide_red() { if (redinterior.opacity != 0) run_storyboard("hide_red_indicator"); } private void run_storyboard(string resource_name) { storyboard sb = (storyboard)findresource(resource_name); sb.begin(); } public static readonly dependencyproperty statusproperty = dependencyproperty.register("status", typeof(bool), typeof(redgreenstatusindicator), new propertymetadata(null)); #region inotifypropertychanged members public event propertychangedeventhandler propertychanged; private void objectvaluechanged() { onpropertychanged("status"); } public void onpropertychanged(string propertyname) { if (propertychanged != null) { propertychanged(this, new propertychangedeventargs(propertyname)); } } #endregion }
xaml:
<usercontrol xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:ignorable="d" x:class="manager.redgreenstatusindicator" x:name="usercontrol" d:designwidth="640" d:designheight="480"> <usercontrol.resources> <storyboard x:key="show_green_indicator"> <doubleanimationusingkeyframes begintime="00:00:00" storyboard.targetname="greeninterior" storyboard.targetproperty="(uielement.opacity)"> <splinedoublekeyframe keytime="00:00:00" value="0"/> <splinedoublekeyframe keytime="00:00:00.5000000" value="1"/> </doubleanimationusingkeyframes> </storyboard> <storyboard x:key="hide_green_indicator"> <doubleanimationusingkeyframes begintime="00:00:00" storyboard.targetname="greeninterior" storyboard.targetproperty="(uielement.opacity)"> <splinedoublekeyframe keytime="00:00:00" value="1"/> <splinedoublekeyframe keytime="00:00:00.5000000" value="0"/> </doubleanimationusingkeyframes> </storyboard> <storyboard x:key="show_red_indicator"> <doubleanimationusingkeyframes begintime="00:00:00" storyboard.targetname="redinterior" storyboard.targetproperty="(uielement.opacity)"> <splinedoublekeyframe keytime="00:00:00" value="0"/> <splinedoublekeyframe keytime="00:00:00.5000000" value="1"/> </doubleanimationusingkeyframes> </storyboard> <storyboard x:key="hide_red_indicator"> <doubleanimationusingkeyframes begintime="00:00:00" storyboard.targetname="redinterior" storyboard.targetproperty="(uielement.opacity)"> <splinedoublekeyframe keytime="00:00:00" value="1"/> <splinedoublekeyframe keytime="00:00:00.5000000" value="0"/> </doubleanimationusingkeyframes> </storyboard> </usercontrol.resources> <border borderbrush="{dynamicresource spdc_gray}" background="{dynamicresource spdc_black}" cornerradius="5,5,5,5" borderthickness="1,1,1,1"> <grid margin="2,2,2,2"> <grid.rowdefinitions> <rowdefinition height="0.5*"/> <rowdefinition height="0.5*"/> </grid.rowdefinitions> <border horizontalalignment="stretch" x:name="redinterior" verticalalignment="stretch" width="auto" height="auto" grid.rowspan="2" background="#fff21818" opacity="0"/> <border horizontalalignment="stretch" verticalalignment="stretch" width="auto" height="auto" grid.rowspan="2" x:name="greeninterior" background="#ff1dd286" opacity="0"/> <border margin="0,0,0,0" x:name="reflection" cornerradius="5,5,0,0"> <border.background> <lineargradientbrush endpoint="0.5,1" startpoint="0.5,0"> <gradientstop color="#99ffffff" offset="0"/> <gradientstop color="#33ffffff" offset="1"/> </lineargradientbrush> </border.background> </border> </grid> </border> </usercontrol>
ok, here's control. intended have public dependency property of type bool, databind-to (hopefully). i've decided see if works , i've placed in project along checkbox, used databinding (working in blend) bind status checkbox's ischecked property. expecting have checkbox toggle control's color.
the binding looks this:
<redgreenstatusindicator horizontalalignment="left" margin="100,146,0,0" verticalalignment="top" width="64" height="64" status="{binding path=ischecked, elementname=checkbox, mode=twoway, updatesourcetrigger=propertychanged}" x:name="m_indicator"/> <checkbox margin="212,168,315,0" verticalalignment="top" height="24" content="click me!" style="{dynamicresource glasscheckbox}" foreground="{dynamicresource spdc_white}" x:name="checkbox"/>
also, in window's .loaded i'm doing :
m_indicator.datacontext = this;
here questions:
what on earth have done wrong? able use in listviewitem template ? listview going databound observable_collection of objects contain bool property (which i'm hoping bind to.
what need make work?
try keeping codebehind small possible.
, especially: not put dependency-property "access-property's" setter - code not executed when wpf changes value.
try one:
code-behind:
public partial class statusindicator : usercontrol { public static readonly dependencyproperty isgreenproperty = dependencyproperty.register("isgreen", typeof(bool), typeof(statusindicator), new uipropertymetadata(false)); public bool isgreen { { return (bool) getvalue(isgreenproperty); } set { setvalue(isgreenproperty, value); } } public statusindicator() { initializecomponent(); } }
xaml:
<usercontrol x:class="wpfapplication1.statusindicator" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfapplication1="clr-namespace:wpfapplication1" height="300" width="300" x:name="this"> <usercontrol.template> <controltemplate targettype="{x:type wpfapplication1:statusindicator}"> <controltemplate.triggers> <datatrigger binding="{binding elementname=this, path=isgreen}" value="true"> <datatrigger.enteractions> <beginstoryboard> <storyboard fillbehavior="holdend"> <doubleanimation duration="0:0:0.500" from="0" to="1" storyboard.targetname="green" storyboard.targetproperty="opacity" /> </storyboard> </beginstoryboard> </datatrigger.enteractions> <datatrigger.exitactions> <beginstoryboard> <storyboard> <doubleanimation duration="0:0:0.500" from="1" to="0" storyboard.targetname="green" storyboard.targetproperty="opacity" /> </storyboard> </beginstoryboard> </datatrigger.exitactions> </datatrigger> </controltemplate.triggers> <grid> <rectangle x:name="red" fill="red"/> <rectangle x:name="green" fill="green" opacity="0" /> </grid> </controltemplate> </usercontrol.template> </usercontrol>
Comments
Post a Comment