c# - WPF ItemsControl:- Changes Property of Items inside ItemControle after ItemSource Property of ItemsControl being changed at Run-Time -


i have following scenario:

i have used 1 itemscontrol.

which generates button per itemssource given it?

now,

when hitting nextbutton.[ have mainwindow.xaml ].

the itemssource of itemscontrol(pagecontrol) changes

and also have chagne background of button have contents equals currentpage property per scenario.

suppose,

step 1: in click event of button first change itemssource of itemscontrol.

step 2: i change background of particular button. instead of changes in background getting following error.

this operation valid on elements have template applied. 

note:- i don’t have problem if directly changes background without changes in itemssource.

have @ below code.

mainwindow.xaml

  <window x:class="currentpageproblem.mainwindow"         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"         title="mainwindow" height="350" width="525">     <window.resources>         <style targettype="button" x:key="buttonstyle">             <setter property="template">                 <setter.value>                     <controltemplate targettype="button">                         <border  cornerradius="2,2,2,2"  horizontalalignment="center" x:name="bordertemplate" background="{templatebinding background}">                             <contentpresenter/>                         </border>                         <controltemplate.triggers>                             <trigger property="ismouseover" value="true">                                 <setter targetname="bordertemplate"  property="border.borderbrush" value="gray" />                                 <setter targetname="bordertemplate"  property="border.borderthickness" value="1" />                             </trigger>                             <trigger property="ispressed" value="true">                                 <setter targetname="bordertemplate"  property="border.borderbrush" value="lime" />                             </trigger>                             <trigger property="isfocused" value="true">                                 <setter targetname="bordertemplate"  property="border.background" value="#fd7" />                             </trigger>                             <trigger property="isenabled" value="false">                                 <setter targetname="bordertemplate"  property="border.background" value="lightgray"></setter>                             </trigger>                         </controltemplate.triggers>                     </controltemplate>                 </setter.value>             </setter>         </style>     </window.resources>     <grid>         <grid.rowdefinitions>             <rowdefinition height="47*" />             <rowdefinition height="264*" />         </grid.rowdefinitions>         <itemscontrol name="pagecontrol" itemssource="{binding path=pagecollection}" grid.row="0">             <itemscontrol.template>                 <controltemplate targettype="itemscontrol">                     <border >                         <stackpanel>                             <itemspresenter></itemspresenter>                         </stackpanel>                     </border>                 </controltemplate>             </itemscontrol.template>             <itemscontrol.itemspanel x:uid="pageitemtemplate">                 <itemspaneltemplate>                     <stackpanel orientation="horizontal"/>                 </itemspaneltemplate>             </itemscontrol.itemspanel>             <itemscontrol.itemtemplate>                 <datatemplate>                     <button x:name="pagenumberbutton" margin="3,4" style="{staticresource buttonstyle}" content="{binding path=page_number}"></button>                 </datatemplate>             </itemscontrol.itemtemplate>         </itemscontrol>          <button content="next" grid.row="1" height="23" horizontalalignment="left" margin="136,98,0,0" name="nextbutton" verticalalignment="top" width="75" click="button1_click" />     </grid> </window> 

mainwindow.xaml.cs

  public partial class mainwindow : window,inotifypropertychanged         {             observablecollection<pagenumber> pagecollection = new observablecollection<pagenumber>();             public mainwindow()             {                 initializecomponent();                  pagecollection.add(new pagenumber("  0  "));                 pagecollection.add(new pagenumber("  1  "));                 pagecollection.add(new pagenumber("  2  "));                 pagecollection.add(new pagenumber("  3  "));                 pagecollection.add(new pagenumber("  4  "));                 pagecollection.add(new pagenumber("  5  "));                  this.datacontext = this;             }              public observablecollection<pagenumber> pagecollection             {                 { return this.pagecollection; }                 set                  {                      this.pagecollection = value;                     this.onpropertychanged("pagecollection");                 }             }              private int currentpage;             public int currentpage             {                 { return currentpage; }                 set                  {                      currentpage = value;                     this.onpropertychanged("currentpage");                 }             }              private void button1_click(object sender, routedeventargs e)             {    #region --  if comment code there no problem,,,problem occures when uncomment code,,, --             pagecollection.clear();              pagecollection.add(new pagenumber("  0  "));             pagecollection.add(new pagenumber("  1  "));             pagecollection.add(new pagenumber("  2  "));             #endregion                   (int = 0; < pagecontrol.items.count; i++)                 {                     var container = pagecontrol.itemcontainergenerator.containerfromindex(i) contentpresenter;                     var button = container.contenttemplate.findname("pagenumberbutton", container) button;                      if (button.content.equals(string.format("  {0}  ", currentpage)))                     {                         button.background = brushes.navajowhite;                     }                     else                     {                         button.background = nextbutton.background;                     }                 }                 currentpage++;             }                #region --  inotifypropertychanged members  --              public event propertychangedeventhandler propertychanged;              public void onpropertychanged(string propertynamearg)             {                 propertychangedeventhandler handler = this.propertychanged;                 if (handler != null)                 {                     handler(this,new propertychangedeventargs(propertynamearg));                 }             }             #endregion         }          public class pagenumber          {             private string page_number;             public pagenumber(string pagenumberarg)             {                 this.page_number = pagenumberarg;             }             public string page_number             {                 { return page_number; }                 set                  {                     page_number = value;                  }             }         }  

there's no need of inotifypropertychanged interface on derived object dependencyobject. should use dependencyproperty instead.

it not practice change whole observablecollection, create 1 , don't destroy it: clear instead.

it's wrong practice access items hosted inside itemscontrol (more in general inside visual tree). within button click handler write following:

button btn = (button)e.originalsource; pagenumber pn = (pagenumber)btn.datacontext; this.currentpage = pn.page; 

however, must add new property named "page" (type "int") in pagenumber class.

to control button color, i'd use converter multibinding.

public class buttoncolorconverter : imultivalueconverter {     public object convert(object[] values, type targettype, object parameter, cultureinfo culture)     {         int current = (int)values[0];         int button = (int)values[1];          return button == current             ? brushes.navajowhite             : brushes.xxx;  //set desired color      }      public object[] convertback(object value, type[] targettypes, object parameter, cultureinfo culture)     {         throw new notimplementedexception();     } } 

however, xaml must changed accordingly:

<itemscontrol.itemtemplate>   <datatemplate>     <button x:name="pagenumberbutton" margin="3,4" style="{staticresource buttonstyle}" content="{binding path=page_number}">       <button.background>         <multibinding converter="{staticresource xxx}">  //specify converter seen above           <binding path="currentpage" relativesource="{relativesource mode=findancestor, ancestortype={x:type window}}" />           <binding path="page" />         </multibinding>       </button.background>     </button>   </datatemplate> </itemscontrol.itemtemplate> 

i didn't test program, should work.

cheers


Comments

Popular posts from this blog

linux - Using a Cron Job to check if my mod_wsgi / apache server is running and restart -

actionscript 3 - TweenLite does not work with object -

jQuery Ajax Render Fragments OR Whole Page -