[WPF] Non-editable state of C1combobox

Source: Internet
Author: User

First, preface

Take a look at WPF's own ComboBox in a non-editable state, with custom ItemTemplate, as shown in the results:

Its currently selected item (within the red box) is the same as the custom ItemTemplate;

But C1combobox's non-editable state (iseditable= "False"):

Always feel that its non-editing status is not completed, although the numbers and English can not be entered, but in the red box will still be able to input Chinese text (QQ Pinyin Input method of Chinese input state); and in the non-editable state is not like the Combobox's non-editable state can display the custom ItemTemplate effect This article describes how to use C1combobox to mimic the non-editing state effect of a ComboBox.

Second, the solution

First analyze the control structure of the C1combobox:

Where the Comboheader part is displayed by switching back and forth from two controls,

Internal C1textboxbase _elementeditcontrol; Internal ContentPresenter _elementcontentcontrol;

_elementeditcontrol is the control that is displayed in the edit state, _elementcontentcontrol the control that is displayed in the non-editable state (the custom ItemTemplate can be displayed);

The two control transformations display the following methods (C1texteditablecontentcontrol):

1 protected Internal voidUpdatevisualstate ()2{3     if( This. Editcontrol = =NULL|| This. ContentControl = =NULL)4{5         return;6}7     if( This. Isineditmode | | This. Isdropdownopen)8{9          This. Editcontrol.opacity = 1.0;Ten          This. Editcontrol.istabstop =true; One          This. Editcontrol.ishittestvisible =true; A          This. contentcontrol.visibility = visibility.collapsed; -          This. Contentcontrol.content =NULL; -} the     Else -{ -          This. editcontrol.opacity = 1.4012984643248171E-45; -          This. Editcontrol.istabstop =false; +          This. Editcontrol.ishittestvisible =false; -          This. contentcontrol.visibility = visibility.visible; +          This. Contentcontrol.content = This. Actualcontent; A} at     Base. Cursor = ( This. Iseditable? Cursors.IBeam:Cursors.Arrow); -} - //Note: Editcontrol corresponds to _elementeditcontrol,contentcontrol corresponding to _elementcontentcontrol;

That is, when this. Isineditmode | | this. When Isdropdownopen is false, the custom Itemplate can be displayed;

Therefore, when the ScrollViewer shrinks (Isdropdownopen is false), the isineditmode of the Comboheader is set to false to ensure that the drop-down option is displayed in Comboheader after the custom itemt Emplate;

Loaded + = (sender, e) =>{    typeof(C1texteditablecontentcontrol)) [0];    Cmb. Isdropdownopenchanged + = (sender2, e2) =    {        false;    };};
1  PublicList<t> getchildobjects<t> (DependencyObject obj, Type TypeName) where t:frameworkelement2{3DependencyObject Child =NULL;4List<t> childlist =NewList<t> ();5 6      for(inti = 0; I <= visualtreehelper.getchildrencount (obj)-1; i++)7{8Child = Visualtreehelper.getchild (obj, i);9 Ten         if(Child isT && ((T) child). GetType () = = typename)) One{ AChildlist.add ((T) child); -} -Childlist.addrange (getchildobjects<t> (Child, TypeName)); the} -     returnChildlist; -}
Getchildobjects Method

However, when Comboheader gets the focus, the Editcontrol is still displayed instead of ContentControl, so add the following code:

false; Editbox.gotfocus + = (sender2, E2) =>{    false;};

It is important to note that if editbox.iseditable = falseis not set; , click two times Comboheader or will enter the editing state, show Editcontrol ...

Continue however, when you click the Arrowtoggle button to expand the ScrollViewer, will still show the editing state, this is troublesome, check the source, the operation will trigger the Updateswappedout method to modify the _elementcomboheader Actualcontent, which in turn triggers the Updatevisualstate method above, at which point the Isdropdownopen property of ScrollViewer is true, resulting in the display of the editing state, not the custom ItemTemplate;

1 Private voidUpdateswappedout ()2{3     if( This. _elementcomboheader = =NULL)4{5         return;6}7      This. _elementcomboheader.isdropdownopen = This. Isdropdownopen;8C1comboboxitem C1comboboxitem =NULL;9      This. _isheaderupdate =true;Ten      This. _elementcomboheader.actualcontent =NULL; One      This. _isheaderupdate =false; A      This. _elementcomboheader.updateiswatermarked (); -      This. _elementcomboheader.updatevisualstate (); -     if( This. Swappedoutitem! =NULL) the{ -          This. Swappedoutitem.swappedout =false; -          This. Swappedoutitem =NULL; -} +     if( This. SelectedItem = =NULL) -{ +         return; A} at     if( This. SelectedIndex! =-1) -{ -C1comboboxitem = (C1comboboxitem)Base. Itemcontainergenerator.containerfromindex ( This. SelectedIndex); -         if(C1comboboxitem! =NULL&&! This. Isdropdownopen) -{ -              This. Swappedoutitem = C1comboboxitem; inC1comboboxitem.swappedout =true; -} to} +     if(C1comboboxitem = =NULL) -{ theC1comboboxitem = ( This. SelectedItem asC1comboboxitem); *} $      This. _isheaderupdate =true;Panax Notoginseng     if(C1comboboxitem = =NULL) -{ the         if(Base. Itemstringformat! =NULL&&! This. Iseditable &&Base. ItemTemplate = =NULL) +{ A              This. _elementcomboheader.actualcontent = This. Formattedstring (Base. Itemstringformat, This. SelectedItem); the} +         Else -{ $              This. _elementcomboheader.actualcontent = This. SelectedItem; $} -} -     Else if(Base. Itemstringformat! =NULL&&! This. Iseditable &&Base. ItemTemplate = =NULL) the{ -          This. _elementcomboheader.actualcontent = This. Formattedstring (Base. Itemstringformat, c1comboboxitem.content);Wuyi} the     Else -{ Wu          This. _elementcomboheader.actualcontent = c1comboboxitem.content; -} About      This. _isheaderupdate =false; $      This. _elementcomboheader.isdirty =false; -}
View Code

I can't find it. How to disable triggering of the Updateswappedout method, or how to set Isdropdownopen to false after triggering, so take Editcontrol and ContentControl two controls out, and then write a Updatevisualstate to update the conversion of two States;

1 Private voidUpdatevisualstate ()2{3     if( This. Editcontrol = =NULL|| This. ContentControl = =NULL)4{5         return;6}7      This. editcontrol.opacity = 1.4012984643248171E-45;8      This. Editcontrol.istabstop =false;9      This. Editcontrol.ishittestvisible =false;Ten      This. contentcontrol.visibility = visibility.visible; OneC1comboboxitem Cmbi = ((C1comboboxitem) CMB. Itemcontainergenerator.containerfromindex (CMB. SelectedIndex)); A      This. Contentcontrol.content = Cmbi. Content; -     Base. Cursor = (editbox.iseditable? Cursors.IBeam:Cursors.Arrow); -}
  1 editcontrol = getchildobjects<control> (CMB, "editcontrol") [0];   2 ContentControl = getchildobjects<contentpresenter> (CMB, "ContentControl") [0];   3 CMB. Isdropdownopenchanged + = (sender2, e2) =  4 {  5     //Editbox.isineditmode = false;   6     Updatevisualstate ();   7 };
1  PublicList<t> getchildobjects<t> (DependencyObject obj,stringName) where t:frameworkelement2{3DependencyObject Child =NULL;4List<t> childlist =NewList<t> ();5 6      for(inti = 0; I <= visualtreehelper.getchildrencount (obj)-1; i++)7{8Child = Visualtreehelper.getchild (obj, i);9 Ten         if(Child isT && ((T) child). Name = = Name |string. IsNullOrEmpty (name))) One{ AChildlist.add ((T) child); -} -Childlist.addrange (getchildobjects<t> (Child, name)); the} -     returnChildlist; -}

All over, the effect is as follows:

Initial state:

Expand Status:

Select the post-change state:

Third, Resources download

1, demo project download: http://files.cnblogs.com/files/memento/C1ComboBoxSample.7z

[WPF] Non-editable state of C1combobox

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.