11namespace SuggestBoxLib
22{
3- using Interfaces ;
4- using System . Windows ;
5- using System . Windows . Controls ;
6- using System . Windows . Input ;
7-
8- /// <summary>
9- /// Implements a text based control that updates a list of suggestions
10- /// when user updates a given text based path -> TextChangedEvent is raised.
11- ///
12- /// This control uses <see cref="ISuggestSource"/> and HierarchyHelper
13- /// to suggest entries in a seperate popup as the user types.
14- /// </summary>
15- public class SuggestBox : SuggestBoxBase
16- {
17- #region fields
18-
19- /// <summary>
20- /// Implements the backing store for the <see cref="TextChangedCommand"/> dependency property.
21- /// </summary>
22- public static readonly DependencyProperty TextChangedCommandProperty =
23- DependencyProperty . Register ( "TextChangedCommand" ,
24- typeof ( ICommand ) , typeof ( SuggestBox ) , new PropertyMetadata ( null ) ) ;
25-
26- #endregion fields
27-
28- #region Constructor
29-
30- /// <summary>
31- /// Static class constructor.
32- /// </summary>
33- static SuggestBox ( )
34- {
35- DefaultStyleKeyProperty . OverrideMetadata ( typeof ( SuggestBox ) ,
36- new FrameworkPropertyMetadata ( typeof ( SuggestBox ) ) ) ;
37- }
38-
39- /// <summary>
40- /// Class constructor
41- /// </summary>
42- public SuggestBox ( )
43- {
44- IsVisibleChanged += SuggestBox_IsVisibleChanged ;
45- }
46-
47- #endregion Constructor
48-
49- #region Public Properties
50-
51- /// <summary>
52- /// Gets/sets a command that should be executed whenever the text in the textbox
53- /// portion of this control has changed.
54- /// </summary>
55- public ICommand TextChangedCommand
56- {
57- get { return ( ICommand ) GetValue ( TextChangedCommandProperty ) ; }
58- set { SetValue ( TextChangedCommandProperty , value ) ; }
59- }
60-
61- #endregion Public Properties
62-
63- #region Methods
64-
65- /// <summary>
66- /// Method executes when the <see cref="SuggestBoxBase.EnableSuggestions"/> dependency property
67- /// has changed its value.
68- ///
69- /// Overwrite this method if you want to consume changes of this property.
70- /// </summary>
71- /// <param name="e"></param>
72- override protected void OnEnableSuggestionChanged ( DependencyPropertyChangedEventArgs e )
73- {
74- base . OnEnableSuggestionChanged ( e ) ;
75-
76- if ( ( ( bool ) e . NewValue ) == true )
77- QueryForSuggestions ( ) ;
78- }
79-
80- /// <summary>
81- /// Method executes when the visibility of the control is changed to query for
82- /// suggestions if this was enabled...
83- /// </summary>
84- /// <param name="sender"></param>
85- /// <param name="e"></param>
86- private void SuggestBox_IsVisibleChanged ( object sender , DependencyPropertyChangedEventArgs e )
87- {
88- if ( ( ( bool ) e . NewValue ) == true )
89- QueryForSuggestions ( ) ;
90- }
91-
92- /// <summary>
93- /// Method executes when new text is entered in the textbox portion of the control.
94- /// </summary>
95- /// <param name="e"></param>
96- protected override void OnTextChanged ( TextChangedEventArgs e )
97- {
98- base . OnTextChanged ( e ) ;
99-
100- if ( string . IsNullOrEmpty ( this . Text ) == false )
101- IsHintVisible = false ;
102- else
103- IsHintVisible = true ;
104-
105- QueryForSuggestions ( ) ;
106- }
107-
108- private void QueryForSuggestions ( )
109- {
110- // A change during disabled state is likely to be caused by a bound property
111- // in a viewmodel (a machine based edit rather than user input)
112- // -> Lets break the message loop here to avoid unnecessary CPU processings...
113- if ( this . IsEnabled == false || this . IsLoaded == false )
114- return ;
115-
116- // Text change is likely to be from property change so we ignore it
117- // if control is invisible or suggestions are currently not requested
118- if ( Visibility != Visibility . Visible || EnableSuggestions == false )
119- return ;
120-
121- if ( ParentWindowIsClosing == true )
122- return ;
123-
124- ICommand changedCommand = this . TextChangedCommand ;
125-
126- // There may not be a command bound to this after all
127- if ( changedCommand == null )
128- return ;
129-
130- var item = this . Text ;
131-
132- // Check whether this attached behaviour is bound to a RoutedCommand
133- if ( changedCommand is RoutedCommand )
134- {
135- // Execute the routed command
136- ( changedCommand as RoutedCommand ) . Execute ( item , this ) ;
137- }
138- else
139- {
140- // Execute the Command as bound delegate
141- changedCommand . Execute ( item ) ;
142- }
143- }
144-
145- #endregion Methods
146- }
3+ using Interfaces ;
4+ using System . Windows ;
5+ using System . Windows . Controls ;
6+ using System . Windows . Input ;
7+
8+ /// <summary>
9+ /// Implements a text based control that updates a list of suggestions
10+ /// when user updates a given text based path -> TextChangedEvent is raised.
11+ ///
12+ /// This control uses <see cref="ISuggestSource"/> and HierarchyHelper
13+ /// to suggest entries in a separate popup as the user types.
14+ /// </summary>
15+ public class SuggestBox : SuggestBoxBase
16+ {
17+ #region fields
18+ public static readonly RoutedEvent QueryChangedEvent = EventManager . RegisterRoutedEvent ( nameof ( QueryChanged ) , RoutingStrategy . Bubble , typeof ( RoutedPropertyChangedEventHandler < string > ) , typeof ( SuggestBox ) ) ;
19+ public static readonly DependencyProperty TextChangedCommandProperty = DependencyProperty . Register ( nameof ( TextChangedCommand ) , typeof ( ICommand ) , typeof ( SuggestBox ) , new PropertyMetadata ( null ) ) ;
20+
21+ public event RoutedPropertyChangedEventHandler < string > QueryChanged
22+ {
23+ add => AddHandler ( QueryChangedEvent , value ) ;
24+ remove => RemoveHandler ( QueryChangedEvent , value ) ;
25+ }
26+
27+ #endregion fields
28+
29+ #region Constructor
30+ static SuggestBox ( )
31+ {
32+ DefaultStyleKeyProperty . OverrideMetadata ( typeof ( SuggestBox ) , new FrameworkPropertyMetadata ( typeof ( SuggestBox ) ) ) ;
33+ }
34+
35+ public SuggestBox ( )
36+ {
37+ IsVisibleChanged += SuggestBox_IsVisibleChanged ;
38+ }
39+
40+ #endregion Constructor
41+
42+ #region Public Properties
43+
44+ /// <summary>
45+ /// Gets/sets a command that should be executed whenever the text in the textbox
46+ /// portion of this control has changed.
47+ /// </summary>
48+ public ICommand TextChangedCommand
49+ {
50+ get { return ( ICommand ) GetValue ( TextChangedCommandProperty ) ; }
51+ set { SetValue ( TextChangedCommandProperty , value ) ; }
52+ }
53+
54+ #endregion Public Properties
55+
56+ #region Methods
57+
58+ /// <summary>
59+ /// Method executes when the <see cref="SuggestBoxBase.EnableSuggestions"/> dependency property has changed its value.
60+ /// </summary>
61+ protected override void OnEnableSuggestionChanged ( DependencyPropertyChangedEventArgs e )
62+ {
63+ base . OnEnableSuggestionChanged ( e ) ;
64+
65+ if ( ( bool ) e . NewValue == true )
66+ QueryForSuggestions ( ) ;
67+ }
68+
69+ /// <summary>
70+ /// Method executes when the visibility of the control is changed to query for
71+ /// suggestions if this was enabled...
72+ /// </summary>
73+ private void SuggestBox_IsVisibleChanged ( object sender , DependencyPropertyChangedEventArgs e )
74+ {
75+ if ( ( ( bool ) e . NewValue ) == true )
76+ QueryForSuggestions ( ) ;
77+ }
78+
79+ /// <summary>
80+ /// Method executes when new text is entered in the textbox portion of the control.
81+ /// </summary>
82+ protected override void OnTextChanged ( TextChangedEventArgs e )
83+ {
84+ base . OnTextChanged ( e ) ;
85+
86+ IsHintVisible = string . IsNullOrEmpty ( this . Text ) ;
87+
88+ QueryForSuggestions ( ) ;
89+ }
90+
91+ private void QueryForSuggestions ( )
92+ {
93+ // A change during disabled state is likely to be caused by a bound property
94+ // in a viewmodel (a machine based edit rather than user input)
95+ // -> Lets break the message loop here to avoid unnecessary CPU processings...
96+ if ( this . IsEnabled == false || this . IsLoaded == false )
97+ return ;
98+
99+ // Text change is likely to be from property change so we ignore it
100+ // if control is invisible or suggestions are currently not requested
101+ if ( Visibility != Visibility . Visible || EnableSuggestions == false )
102+ return ;
103+
104+ if ( ParentWindowIsClosing )
105+ return ;
106+
107+ this . RaiseEvent ( new RoutedPropertyChangedEventArgs < string > ( string . Empty , Text , QueryChangedEvent ) ) ;
108+
109+ // Check whether this attached behaviour is bound to a RoutedCommand
110+ if ( this . TextChangedCommand is RoutedCommand command )
111+ {
112+ // Execute the routed command
113+ command . Execute ( this . Text , this ) ;
114+ }
115+ else
116+ {
117+ // Execute the Command as bound delegate if anything bound
118+ TextChangedCommand ? . Execute ( this . Text ) ;
119+ }
120+ }
121+ #endregion Methods
122+ }
147123}
0 commit comments