Issue with multiselect combobox control in Windows 8 -
i creating multiselect combobox in windows 8 shown in below image:
for have created custom control code mentioned below: problem below code 1. on selecting all items not selected 2. selected items not displayed in textbox
how can fix that. need asap pls
xaml:
<usercontrol x:class="app5.multiselectcombobox" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:app5" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:ignorable="d" d:designheight="300" x:name="thisuc" d:designwidth="400"> <combobox x:name="multiselectcombo" scrollviewer.horizontalscrollbarvisibility="auto" scrollviewer.verticalscrollbarvisibility="auto" width="400" height="20" > <combobox.itemtemplate> <datatemplate> <checkbox content="{binding title}" foreground="black" ischecked="{binding elementname=thisuc, path=isselected, mode=twoway}" click="checkbox_click" /> </datatemplate> </combobox.itemtemplate> <controltemplate targettype="combobox"> <grid > <togglebutton x:name="togglebutton" grid.column="2" ischecked="{templatebinding isdropdownopen}" clickmode="press" horizontalcontentalignment="left" > <togglebutton.template> <controltemplate> <grid> <grid.columndefinitions> <columndefinition width="*"/> <columndefinition width="18"/> </grid.columndefinitions> <border x:name="border" grid.columnspan="2" cornerradius="2" background="white" borderbrush="black" borderthickness="1,1,1,1" /> <border x:name="bordercomp" grid.column="0" cornerradius="2" margin="1" background="white" borderbrush="black" borderthickness="0,0,0,0" > <textblock foreground="black" text="{templatebinding textvalue}" padding="3" /> </border> <path x:name="arrow" grid.column="1" fill="black" horizontalalignment="center" verticalalignment="center" data="m 0 0 l 4 4 l 8 0 z"/> </grid> </controltemplate> </togglebutton.template> </togglebutton> <popup name="popup" isopen="{templatebinding isdropdownopen}" > <grid name="dropdown" minwidth="{templatebinding actualwidth}" maxheight="{templatebinding maxdropdownheight}"> <border x:name="dropdownborder" borderthickness="1" background="white" borderbrush="black"/> <scrollviewer margin="4,6,4,6" datacontext="{binding}"> <stackpanel /> </scrollviewer> </grid> </popup> </grid> <!--<controltemplate.triggers> <trigger property="hasitems" value="false"> <setter targetname="dropdownborder" property="minheight" value="95"/> </trigger> <trigger sourcename="popup" property="popup.allowstransparency" value="true"> <setter targetname="dropdownborder" property="cornerradius" value="4"/> <setter targetname="dropdownborder" property="margin" value="0,2,0,0"/> </trigger> </controltemplate.triggers>--> </controltemplate> </combobox> </usercontrol>
c#
using system; using system.collections.generic; using system.collections.objectmodel; using system.componentmodel; using system.io; using system.linq; using system.text; using windows.foundation; using windows.foundation.collections; using windows.ui.xaml; using windows.ui.xaml.controls; using windows.ui.xaml.controls.primitives; using windows.ui.xaml.data; using windows.ui.xaml.input; using windows.ui.xaml.media; using windows.ui.xaml.navigation; // user control item template documented @ http://go.microsoft.com/fwlink/?linkid=234236 namespace app5 { public sealed partial class multiselectcombobox : usercontrol { private observablecollection<node> _nodelist; public multiselectcombobox() { initializecomponent(); _nodelist = new observablecollection<node>(); } #region dependency properties public static readonly dependencyproperty itemssourceproperty = dependencyproperty.register("itemssource", typeof(dictionary<string, object>), typeof(multiselectcombobox), new propertymetadata(null, new propertychangedcallback(multiselectcombobox.onitemssourcechanged))); public static readonly dependencyproperty selecteditemsproperty = dependencyproperty.register("selecteditems", typeof(dictionary<string, object>), typeof(multiselectcombobox), new propertymetadata(null, new propertychangedcallback(multiselectcombobox.onselecteditemschanged))); public static readonly dependencyproperty textproperty = dependencyproperty.register("textvalue", typeof(string), typeof(multiselectcombobox), new propertymetadata(null)); public static readonly dependencyproperty defaulttextproperty = dependencyproperty.register("defaulttext", typeof(string), typeof(multiselectcombobox), new propertymetadata(null)); public dictionary<string, object> itemssource { { return (dictionary<string, object>)getvalue(itemssourceproperty); } set { setvalue(itemssourceproperty, value); } } public dictionary<string, object> selecteditems { { return (dictionary<string, object>)getvalue(selecteditemsproperty); } set { setvalue(selecteditemsproperty, value); } } public string textvalue { { return (string)getvalue(textproperty); } set { setvalue(textproperty, value); } } public string defaulttext { { return (string)getvalue(defaulttextproperty); } set { setvalue(defaulttextproperty, value); } } #endregion #region events private static void onitemssourcechanged(dependencyobject d, dependencypropertychangedeventargs e) { multiselectcombobox control = (multiselectcombobox)d; control.displayincontrol(); } private static void onselecteditemschanged(dependencyobject d, dependencypropertychangedeventargs e) { multiselectcombobox control = (multiselectcombobox)d; control.selectnodes(); control.settext(); } private void checkbox_click(object sender, routedeventargs e) { checkbox clickedbox = (checkbox)sender; if (clickedbox.content == "all") { if (clickedbox.ischecked.value) { foreach (node node in _nodelist) { node.isselected = true; } } else { foreach (node node in _nodelist) { node.isselected = false; } } } else { int _selectedcount = 0; foreach (node s in _nodelist) { if (s.isselected && s.title != "all") _selectedcount++; } if (_selectedcount == _nodelist.count - 1) _nodelist.firstordefault(i => i.title == "all").isselected = true; else _nodelist.firstordefault(i => i.title == "all").isselected = false; } setselecteditems(); settext(); } #endregion #region methods private void selectnodes() { foreach (keyvaluepair<string, object> keyvalue in selecteditems) { node node = _nodelist.firstordefault(i => i.title == keyvalue.key); if (node != null) node.isselected = true; } } private void setselecteditems() { if (selecteditems == null) selecteditems = new dictionary<string, object>(); selecteditems.clear(); foreach (node node in _nodelist) { if (node.isselected && node.title != "all") { if (this.itemssource.count > 0) selecteditems.add(node.title, this.itemssource[node.title]); } } } private void displayincontrol() { _nodelist.clear(); if (this.itemssource.count > 0) _nodelist.add(new node("all")); foreach (keyvaluepair<string, object> keyvalue in this.itemssource) { node node = new node(keyvalue.key); _nodelist.add(node); } multiselectcombo.itemssource = _nodelist; } private void settext() { if (this.selecteditems != null) { stringbuilder displaytext = new stringbuilder(); foreach (node s in _nodelist) { if (s.isselected == true && s.title == "all") { displaytext = new stringbuilder(); displaytext.append("all"); break; } else if (s.isselected == true && s.title != "all") { displaytext.append(s.title); displaytext.append(','); } } this.textvalue = displaytext.tostring().trimend(new char[] { ',' }); } // set defaulttext if nothing else selected if (string.isnullorempty(this.textvalue)) { this.textvalue = this.defaulttext; } } #endregion } public class node : inotifypropertychanged { private string _title; private bool _isselected; #region ctor public node(string title) { title = title; } #endregion #region properties public string title { { return _title; } set { _title = value; notifypropertychanged("title"); } } public bool isselected { { return _isselected; } set { _isselected = value; notifypropertychanged("isselected"); } } #endregion public event propertychangedeventhandler propertychanged; protected void notifypropertychanged(string propertyname) { if (propertychanged != null) { propertychanged(this, new propertychangedeventargs(propertyname)); } } } }
i think understand want. overall, recommend different approach. recommend, one, not use combobox
accomplish - itemscontrol
accomplish want less work , overhead. using popup
great, let me show simplified way (this best part) works way asking in question.
here's xaml:
<grid background="{staticresource applicationpagebackgroundthemebrush}"> <grid.datacontext> <local:viewmodel/> </grid.datacontext> <stackpanel orientation="vertical" verticalalignment="center" horizontalalignment="center"> <textbox width="200" fontsize="24" text="{binding header, mode=twoway}" isreadonly="true" textwrapping="wrap" maxheight="200" /> <scrollviewer verticalscrollbarvisibility="auto" maxheight="200" width="200" background="white"> <itemscontrol itemssource="{binding items}"> <itemscontrol.itemtemplate> <datatemplate> <checkbox content="{binding text}" fontsize="24" foreground="black" ischecked="{binding ischecked, mode=twoway}" isthreestate="false" /> </datatemplate> </itemscontrol.itemtemplate> </itemscontrol> </scrollviewer> </stackpanel> </grid>
here's code-behind:
public class item : bindablebase { public string text { get; set; } bool _ischecked = default(bool); public bool ischecked { { return _ischecked; } set { setproperty(ref _ischecked, value); } } } public class viewmodel : bindablebase { public viewmodel() { _items = new observablecollection<item>(enumerable.range(1, 10) .select(x => new item() { text = string.format("item {0}", x), ischecked = (x < 4) ? true : false, })); foreach (var item in this.items) item.propertychanged += (s, e) => base.raisepropertychanged("header"); } public string header { { var array = this.items .where(x => x.ischecked) .select(x => x.text).toarray(); if (!array.any()) return "none"; return string.join("; ", array); } } observablecollection<item> _items; public observablecollection<item> items { { return _items; } } } public abstract class bindablebase : inotifypropertychanged { public event propertychangedeventhandler propertychanged; protected void setproperty<t>(ref t storage, t value, [system.runtime.compilerservices.callermembername] string propertyname = null) { if (!object.equals(storage, value)) { storage = value; if (propertychanged != null) propertychanged(this, new propertychangedeventargs(propertyname)); } } protected void raisepropertychanged([system.runtime.compilerservices.callermembername] string propertyname = null) { if (propertychanged != null) propertychanged(this, new propertychangedeventargs(propertyname)); } }
best of luck!
Comments
Post a Comment