網(wǎng)站內(nèi)部鏈接有什么作用有什么平臺(tái)可以發(fā)廣告
一種方法是使用事件(包括MVVM的綁定)
<ComboBox TextBoxBase.TextChanged="ComboBox_TextChanged" />
然而運(yùn)行時(shí)就會(huì)發(fā)現(xiàn),這個(gè)事件在瘋狂的觸發(fā),很頻繁
在實(shí)際應(yīng)用中,如果關(guān)聯(lián)查詢數(shù)據(jù)庫,網(wǎng)絡(luò)吞吐什么的,就會(huì)卡頓
另一種方法是使用IsTextSearchEnabled屬性,在文本框敲鍵盤會(huì)自動(dòng)選擇相關(guān)項(xiàng)
<ComboBox IsTextSearchEnabled="True" IsTextSearchCaseSensitive="False" TextSearch.TextPath="Name" />
然而又有新的問題,選擇項(xiàng)不會(huì)顯示到文本框(文本框仍然是鍵盤敲的內(nèi)容,當(dāng)然還可能跟Framework版本有關(guān)),于是我們需要更深入
試驗(yàn)數(shù)據(jù)含 3 個(gè)項(xiàng)
<ComboBox TextBoxBase.TextChanged="ComboBox_TextChanged"><ComboBoxItem>啊啊啊</ComboBoxItem><ComboBoxItem>哦哦哦</ComboBoxItem><ComboBoxItem>呃呃呃</ComboBoxItem></ComboBox>
試驗(yàn)一:綁定?TextChanged 和 SelectionChanged 調(diào)試
private void Combobox_TextChanged(object sender, TextChangedEventArgs e){// e.OriginalSource == TextBox, e.Source == sender == Comboboxvar tb = e.OriginalSource as TextBox;var cb = e.Source as ComboBox;var cs = e.Changes.ToArray();int alen = -1, offs = -1, rlen = -1;if (cs.Length > 0) { alen = cs[0].AddedLength; offs = cs[0].Offset; rlen = cs[0].RemovedLength; }var str1 = TextSearch.GetText(cmbStudios);System.Diagnostics.Debug.Print($"TextBox.Text={tb.Text},ComboBox.Text={cb.Text},TextSearch.Text={str1},Action={e.UndoAction}, Changes={cs.Length}: [0]={{{alen},{offs},{rlen}}}\r\n");}private void Combobox_SelectionChanged(object sender, SelectionChangedEventArgs e){var cb = e.Source as ComboBox;System.Diagnostics.Debug.Print($"ComboBox.Text={cb.Text},SelectedItem={cb.SelectedItem}\r\n");}
記錄
TextBox.Text=a,ComboBox.Text=,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,0}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=None, Changes=0: [0]={-1,-1,-1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
ComboBox.Text=啊,SelectedItem=啊啊啊
TextBox.Text=啊啊啊,ComboBox.Text=啊啊啊,TextSearch.Text=,Action=Create, Changes=1: [0]={3,0,1}
也就是選擇項(xiàng)目正常設(shè)置Text屬性,但是現(xiàn)在我們要讓Text改變自動(dòng)選擇項(xiàng)目
試驗(yàn)二:啟用IsTextSearchEnabled屬性
TextBox.Text=a,ComboBox.Text=,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,0}
ComboBox.Text=,SelectedItem=啊啊啊
TextBox.Text=啊,ComboBox.Text=啊啊啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=None, Changes=0: [0]={-1,-1,-1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
TextBox.Text=啊,ComboBox.Text=啊,TextSearch.Text=,Action=Create, Changes=1: [0]={1,0,1}
敲a一次,空格變成“啊”自動(dòng)選擇“啊啊啊”項(xiàng)目,然后就開始抽,完全看不到適當(dāng)?shù)慕槿霑r(shí)機(jī)
用過Win10的都知道,文件夾右上角的搜索框,能在輸入法完成后才開始搜索,所以一定是可以實(shí)現(xiàn)的
換網(wǎng),查英文資料發(fā)現(xiàn)Win11中有TextCompositionEnded事件,但是WPF中找不到,類似的TextCompositionManager外掛
實(shí)驗(yàn)三:啟用TextComposition事件
<TextBox TextCompositionManager.TextInputStart="TextBox_TextInputStart" TextCompositionManager.TextInputUpdate="TextBox_TextInputUpdate" TextCompositionManager.TextInput="TextBox_TextInput" />
事件響應(yīng)代碼
private void TextBox_TextInputStart(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInputStart() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}private void TextBox_TextInputUpdate(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInputUpdate() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}private void TextBox_TextInput(object sender, TextCompositionEventArgs e){var tc = e.TextComposition;string text = $" CompositionText={tc.CompositionText},ControlText={tc.ControlText},ControlText={tc.SystemText},Text={tc.Text} ";System.Diagnostics.Debug.Print($"TextInput() ControlText={e.ControlText},SystemText={e.SystemText},Text={e.Text},TextComposition={{{text}}}\r\n");}
記錄
TextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
沒有TextInput事件!
英文資料顯示,會(huì)依次觸發(fā) TextCompositionStarted、TextChanging、TextChanged、TextCompositionChanged、TextCompositionEnded 事件
思考是隧道事件的問題:
如上面提到的外掛,WPF中的控件其實(shí)都外掛的,而且還可以自己給現(xiàn)有的類添加屬性、方法和事件(參考:Binding Property)
由于可以任意的排布所有的控件,因此事件的響應(yīng)與傳統(tǒng)的MFC控件就開始有差異
如圖,如果鼠標(biāo)點(diǎn)在2上,傳統(tǒng)的事件會(huì)由2響應(yīng),容器1對(duì)此一無所知
這有什么問題?有沒有問題就看你怎么看問題。
所謂路由事件是把響應(yīng)規(guī)則擴(kuò)展為3類:
1.直接事件:等同傳統(tǒng)事件
2.冒泡事件:從內(nèi)向外依次觸發(fā),直到Handled被設(shè)置
3.隧道事件:從外向內(nèi)依次觸發(fā),直到Handled被設(shè)置,這樣容器就有機(jī)會(huì)在內(nèi)部控件之前做出響應(yīng),事件一般以Preview開頭,常見的如多個(gè)帶滾動(dòng)條的控件互相包含
試驗(yàn)四:加入Preview事件
PreviewTextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
TextInputStart() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=,ControlText=,ControlText=,Text= }
PreviewTextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=a,ControlText=,ControlText=,Text= }
PreviewTextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
TextInputUpdate() ControlText=,SystemText=,Text=,TextComposition={ CompositionText=啊,ControlText=,ControlText=,Text= }
PreviewTextInput() ControlText=,SystemText=,Text=啊,TextComposition={ CompositionText=,ControlText=,ControlText=,Text=啊 }
所有的都可以不管,只看PreviewTextInput檢查Text屬性就是輸入法敲出完整的文本時(shí)
策略響應(yīng)的也就簡單了
1.加入一個(gè)Timer
2.在TextInput事件啟動(dòng)計(jì)時(shí)器,其它如Start和Update時(shí)停止計(jì)時(shí)器
3.計(jì)時(shí)器響應(yīng)執(zhí)行過濾邏輯,然后停止計(jì)時(shí)器
當(dāng)然這是Windows文件搜索框的邏輯,也就是你敲鍵盤很快的話,中途不會(huì)執(zhí)行搜索,你也可以根據(jù)需要進(jìn)行調(diào)整,比如Start也開始計(jì)時(shí)器,如果Update過一段時(shí)間未觸發(fā),一樣執(zhí)行邏輯