Itemscontrol in WPF defines the itemcontainerstyle attribute. As the name suggests, this attribute is used to define the style for each item in itemscontrol.
For example, in ListBox, the container is listboxitem, and in tabcontrol, the container is tabitem.
The following is a simple application of itemcontainerstyle:
XAML:
<Window...> <stackpanel> <ListBox name = "itemscontrol" itemssource = "{binding}"> <ListBox. itemcontainerstyle> <style targettype = "listboxitem"> <setter property = "isselected" value = "{binding isselected, mode = onetime}"/> </style> </ListBox. itemcontainerstyle> <ListBox. itemtemplate> <datatemplate> <textblock text = "{binding text}"/> </datatemplate> </ListBox. itemtemplate> </ListBox> </stackpanel> </WINDOW>
In this section, a ListBox is defined in XAML, and a textblock in its itemtemplate is bound to the text attribute of the data entity. In its itemcontainerstyle, bind the isselected attribute of each item to the isselected of the data entity. The data entity is generated in the followingCodeMedium:
Public partial class comboboxtest: window {public comboboxtest () {initializecomponent (); itemscontrol. datacontext = getdata ();} private object getdata () {collection <Object> DATA = new collection <Object> (); For (INT I = 1; I <= 10; I ++) {data. add (New {text = I. tostring (), isselected = I = 5}) ;}return data ;}}
For simplicity, anonymous objects are used instead of defining entity classes. A total of 10 anonymous entities are generated, and the fifth isselected is set to true. Put these 10 entities into a collection and assign them to the datacontext of the control, in this way, the itemssource binding (itemssource = "{binding}") in XAML will take effect. Of course, you can assign the collection value to itemssource directly.
Run the command. The result is the same as expected. The fifth item is selected.
Replace ListBox in XAML with tabcontrol. The changed XAML is as follows:
<Window...> <stackpanel> <tabcontrol name = "itemscontrol" itemssource = "{binding}"> <tabcontrol. itemcontainerstyle> <style targettype = "tabitem"> <setter property = "isselected" value = "{binding isselected, mode = onetime}"/> </style> </tabcontrol. itemcontainerstyle> <tabcontrol. itemtemplate> <datatemplate> <textblock text = "{binding text}"/> </datatemplate> </tabcontrol. itemtemplate> </tabcontrol> </stackpanel> </WINDOW>
I only changed ListBox to tabcontrol and listboxitem to tabitem, but the C # code was not changed. Try to run it. The result is the same as expected. The fifth item will be selected.
Both ListBox and tabcontrol indirectly inherit from itemscontrol and directly inherit from selector. Is it true that all selector subclass will behave like above?
Actually not. Take out another sub-class ComboBox of selector and try it out.
It is still to change only the XAML without changing the C # code. The modified XAML is as follows:
<Window...> <stackpanel> <ComboBox name = "itemscontrol" itemssource = "{binding}"> <ComboBox. itemcontainerstyle> <style targettype = "comboboxitem"> <setter property = "isselected" value = "{binding isselected, mode = onetime}"/> </style> </ComboBox. itemcontainerstyle> <ComboBox. itemtemplate> <datatemplate> <textblock text = "{binding text}"/> </datatemplate> </ComboBox. itemtemplate> </ComboBox> </stackpanel> </WINDOW>
The effect after running is as follows:
It can be seen that there are no selected items after startup. The fifth item is selected only when the ComboBox is expanded with the mouse. I guess this is because itemcontainerstyle will be applied only after all items are loaded, and ComboBox will not display its items by default, therefore, the ComboBox is selected only when you expand it with the mouse.
There is an imperfect solution for this situation. Modify the getdata method in C # Code as follows:
Private object getdata () {collection <Object> DATA = new collection <Object> (); For (INT I = 1; I <= 10; I ++) {data. add (New {text = I. tostring ()});} return New {DATA = data, selecteddata = data [4]};}
The above Code applies the anonymous object again, assigns the entire object set a value to the data attribute in the new anonymous object, and assigns the fifth item of the set to the selecteddata attribute of the new anonymous object. In this way, the return value of the getdata method-that is, the new anonymous object will be assigned to the datacontext of the control.
Modify the XAML, bind the itemssource of ComboBox to the data attribute of the anonymous object, and bind selectedvalue to the selecteddata attribute of the anonymous object. The modified XAML is as follows:
<Window...> <stackpanel> <ComboBox name = "itemscontrol" itemssource = "{Binding data}" selectedvalue = "{binding selecteddata, mode = onetime}"> <ComboBox. itemtemplate> <datatemplate> <textblock text = "{binding text}"/> </datatemplate> </ComboBox. itemtemplate> </ComboBox> </stackpanel> </WINDOW>
Bind selectedvalue directly this time.StyleWaitItemIt takes effect only after being loaded.
Run the command again. The startup effect is as follows: