Araç penceresine arama ekleme
Uzantınızda bir araç penceresi oluşturduğunuzda veya güncelleştirdiğinizde, Visual Studio'da başka bir yerde görünen arama işlevinin aynısını ekleyebilirsiniz. Bu işlev aşağıdaki özellikleri içerir:
Her zaman araç çubuğunun özel bir alanında bulunan bir arama kutusu.
Arama kutusunun üzerinde yer alan bir ilerleme göstergesi.
Her karakteri girer girmez (anlık arama) veya yalnızca Enter tuşunu seçtikten sonra (isteğe bağlı arama) sonuçları gösterebilme özelliği.
En son aradığınız terimleri gösteren liste.
Aramaları belirli alanlara veya arama hedeflerinin yönlerine göre filtreleme özelliği.
Bu kılavuzu izleyerek aşağıdaki görevleri gerçekleştirmeyi öğreneceksiniz:
VSPackage projesi oluşturma.
Salt okunur TextBox ile UserControl içeren bir araç penceresi oluşturun.
Araç penceresine bir arama kutusu ekleyin.
Arama uygulamasını ekleyin.
bir ilerleme çubuğunun anlık aramasını ve görüntülenmesini etkinleştirin.
Büyük /küçük harf eşleştir seçeneği ekleyin.
Yalnızca Çift satır ara filtresi ekleyin.
VSIX projesi oluşturmak için
- TestSearch adlı bir araç penceresiyle adlı
TestToolWindowSearch
bir VSIX projesi oluşturun. Bunu yaparken yardıma ihtiyacınız varsa bkz . Araç penceresiyle uzantı oluşturma.
Araç penceresi oluşturmak için
Projede
TestToolWindowSearch
TestSearchControl.xaml dosyasını açın.Mevcut
<StackPanel>
bloğu, araç penceresindeki öğesine salt TextBox UserControl okunur bir ekleyen aşağıdaki blokla değiştirin.<StackPanel Orientation="Vertical"> <TextBox Name="resultsTextBox" Height="800.0" Width="800.0" IsReadOnly="True"> </TextBox> </StackPanel>
TestSearchControl.xaml.cs dosyasına aşağıdaki using yönergesini ekleyin:
using System.Text;
button1_Click()
yöntemini kaldırın.TestSearchControl sınıfına aşağıdaki kodu ekleyin.
Bu kod SearchResultsTextBox adlı bir ortak TextBox özellik ve SearchContent adlı bir ortak dize özelliği ekler. Oluşturucuda SearchResultsTextBox metin kutusuna ayarlanır ve SearchContent yeni satırla ayrılmış dize kümesine başlatılır. Metin kutusunun içeriği de dize kümesine başlatılır.
public partial class MyControl : UserControl { public TextBox SearchResultsTextBox { get; set; } public string SearchContent { get; set; } public MyControl() { InitializeComponent(); this.SearchResultsTextBox = resultsTextBox; this.SearchContent = BuildContent(); this.SearchResultsTextBox.Text = this.SearchContent; } private string BuildContent() { StringBuilder sb = new StringBuilder(); sb.AppendLine("1 go"); sb.AppendLine("2 good"); sb.AppendLine("3 Go"); sb.AppendLine("4 Good"); sb.AppendLine("5 goodbye"); sb.AppendLine("6 Goodbye"); return sb.ToString(); } }
Projeyi derleyin ve hata ayıklamaya başlayın. Visual Studio'nun deneysel örneği görüntülenir.
Menü çubuğunda Diğer Windows>Testlerini GörüntüleAra'yı> seçin.
Araç penceresi görüntülenir, ancak arama denetimi henüz görüntülenmez.
Araç penceresine arama kutusu eklemek için
TestSearch.cs dosyasında sınıfına
TestSearch
aşağıdaki kodu ekleyin. Kod, get erişimcisinin SearchEnabled döndürebilmesitrue
için özelliğini geçersiz kılar.Aramayı etkinleştirmek için özelliğini geçersiz kılmanız SearchEnabled gerekir. ToolWindowPane sınıfı, aramayı etkinleştirmeyen bir varsayılan uygulama uygular IVsWindowSearch ve sağlar.
public override bool SearchEnabled { get { return true; } }
Projeyi derleyin ve hata ayıklamaya başlayın. Deneysel örnek görüntülenir.
Visual Studio'nun deneysel örneğinde TestSearch'i açın.
Araç penceresinin üst kısmında Arama filigranı ve büyüteç simgesi içeren bir arama denetimi görüntülenir. Ancak, arama işlemi uygulanmadığından arama henüz çalışmıyor.
Arama uygulamasını eklemek için
Önceki yordamda olduğu gibi bir ToolWindowPaneüzerinde aramayı etkinleştirdiğinizde, araç penceresi bir arama konağı oluşturur. Bu konak, her zaman bir arka plan iş parçacığında gerçekleşen arama işlemlerini ayarlar ve yönetir. ToolWindowPane sınıfı, arama ana bilgisayarının oluşturulmasını ve aramanın ayarlanmasını yönettiğinden, yalnızca bir arama görevi oluşturmanız ve arama yöntemini sağlamanız gerekir. Arama işlemi arka plan iş parçacığında gerçekleşir ve kullanıcı arabirimi iş parçacığında araç penceresi denetimine çağrılar gerçekleşir. Bu nedenle, denetimle ilgilenirken yaptığınız çağrıları yönetmek için ThreadHelper.Invoke* yöntemini kullanmanız gerekir.
TestSearch.cs dosyasına aşağıdaki
using
yönergeleri ekleyin:using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Windows.Controls; using Microsoft.Internal.VisualStudio.PlatformUI; using Microsoft.VisualStudio; using Microsoft.VisualStudio.PlatformUI; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop;
TestSearch
sınıfında, aşağıdaki eylemleri gerçekleştiren aşağıdaki kodu ekleyin:CreateSearch Arama görevi oluşturmak için yöntemini geçersiz kılar.
ClearSearch Metin kutusunun durumunu geri yüklemek için yöntemini geçersiz kılar. Bu yöntem, kullanıcı bir arama görevini iptal ettiğinde ve bir kullanıcı seçenekleri veya filtreleri ayarlayıp kaldırdığında çağrılır. Hem hem de CreateSearch ClearSearch kullanıcı arabirimi iş parçacığında çağrılır. Bu nedenle, ThreadHelper.Invoke* yöntemiyle metin kutusuna erişmeniz gerekmez.
varsayılan uygulamasını IVsSearchTasksağlayan öğesinden VsSearchTaskdevralan adlı
TestSearchTask
bir sınıf oluşturur.içinde
TestSearchTask
oluşturucu, araç penceresine başvuran özel bir alan ayarlar. Arama yöntemini sağlamak için ve OnStopSearch yöntemlerini geçersiz kılarsınızOnStartSearch. OnStartSearch yöntemi, arama işlemini uyguladığınız yerdir. Bu işlem, aramayı gerçekleştirmeyi, arama sonuçlarını metin kutusunda görüntülemeyi ve aramanın tamamlandığını bildirmek için bu yöntemin temel sınıf uygulamasını çağırmayı içerir.
public override IVsSearchTask CreateSearch(uint dwCookie, IVsSearchQuery pSearchQuery, IVsSearchCallback pSearchCallback) { if (pSearchQuery == null || pSearchCallback == null) return null; return new TestSearchTask(dwCookie, pSearchQuery, pSearchCallback, this); } public override void ClearSearch() { TestSearchControl control = (TestSearchControl)this.Content; control.SearchResultsTextBox.Text = control.SearchContent; } internal class TestSearchTask : VsSearchTask { private TestSearch m_toolWindow; public TestSearchTask(uint dwCookie, IVsSearchQuery pSearchQuery, IVsSearchCallback pSearchCallback, TestSearch toolwindow) : base(dwCookie, pSearchQuery, pSearchCallback) { m_toolWindow = toolwindow; } protected override void OnStartSearch() { // Use the original content of the text box as the target of the search. var separator = new string[] { Environment.NewLine }; TestSearchControl control = (TestSearchControl)m_toolWindow.Content; string[] contentArr = control.SearchContent.Split(separator, StringSplitOptions.None); // Get the search option. bool matchCase = false; // matchCase = m_toolWindow.MatchCaseOption.Value; // Set variables that are used in the finally block. StringBuilder sb = new StringBuilder(""); uint resultCount = 0; this.ErrorCode = VSConstants.S_OK; try { string searchString = this.SearchQuery.SearchString; // Determine the results. uint progress = 0; foreach (string line in contentArr) { if (matchCase == true) { if (line.Contains(searchString)) { sb.AppendLine(line); resultCount++; } } else { if (line.ToLower().Contains(searchString.ToLower())) { sb.AppendLine(line); resultCount++; } } // SearchCallback.ReportProgress(this, progress++, (uint)contentArr.GetLength(0)); // Uncomment the following line to demonstrate the progress bar. // System.Threading.Thread.Sleep(100); } } catch (Exception e) { this.ErrorCode = VSConstants.E_FAIL; } finally { ThreadHelper.Generic.Invoke(() => { ((TextBox)((TestSearchControl)m_toolWindow.Content).SearchResultsTextBox).Text = sb.ToString(); }); this.SearchResults = resultCount; } // Call the implementation of this method in the base class. // This sets the task status to complete and reports task completion. base.OnStartSearch(); } protected override void OnStopSearch() { this.SearchResults = 0; } }
Aşağıdaki adımları gerçekleştirerek arama uygulamanızı test edin:
Projeyi yeniden derleyin ve hata ayıklamayı başlatın.
Visual Studio'nun deneysel örneğinde araç penceresini yeniden açın, arama penceresine bir arama metni girin ve ENTER'a tıklayın.
Doğru sonuçlar görünmelidir.
Arama davranışını özelleştirmek için
Arama ayarlarını değiştirerek, arama denetiminin nasıl göründüğü ve aramanın nasıl gerçekleştirildiği konusunda çeşitli değişiklikler yapabilirsiniz. Örneğin, filigranı (arama kutusunda görünen varsayılan metin), arama denetiminin en küçük ve en büyük genişliğini ve ilerleme çubuğunun gösterilip gösterilmeyeceğini değiştirebilirsiniz. Ayrıca, arama sonuçlarının görünmeye başladığı noktayı (isteğe bağlı veya anlık arama) ve son arama yaptığınız terimlerin listesinin gösterilip gösterilmeyeceğini de değiştirebilirsiniz. Ayarların tam listesini SearchSettingsDataSource sınıfında bulabilirsiniz.
* TestSearch.cs* dosyasına aşağıdaki kodu sınıfına
TestSearch
ekleyin. Bu kod, isteğe bağlı arama yerine hızlı aramayı etkinleştirir (kullanıcının ENTER'a tıklaması gerekmeyecek anlamına gelir). Kod, sınıfındakiProvideSearchSettings
TestSearch
yöntemini geçersiz kılar ve bu, varsayılan ayarları değiştirmek için gereklidir.public override void ProvideSearchSettings(IVsUIDataSource pSearchSettings) { Utilities.SetValue(pSearchSettings, SearchSettingsDataSource.SearchStartTypeProperty.Name, (uint)VSSEARCHSTARTTYPE.SST_INSTANT);}
Çözümü yeniden oluşturup hata ayıklayıcısını yeniden başlatarak yeni ayarı test edin.
Arama kutusuna her karakter girdiğinizde arama sonuçları görüntülenir.
yönteminde
ProvideSearchSettings
, ilerleme çubuğunun görüntülenmesini sağlayan aşağıdaki satırı ekleyin.public override void ProvideSearchSettings(IVsUIDataSource pSearchSettings) { Utilities.SetValue(pSearchSettings, SearchSettingsDataSource.SearchStartTypeProperty.Name, (uint)VSSEARCHSTARTTYPE.SST_INSTANT); Utilities.SetValue(pSearchSettings, SearchSettingsDataSource.SearchProgressTypeProperty.Name, (uint)VSSEARCHPROGRESSTYPE.SPT_DETERMINATE); }
İlerleme çubuğunun görünmesi için ilerlemenin bildirilmesi gerekir. İlerleme durumunu bildirmek için sınıfının yönteminde
OnStartSearch
aşağıdaki kodun açıklamalarını kaldırınTestSearchTask
:SearchCallback.ReportProgress(this, progress++, (uint)contentArr.GetLength(0));
İlerleme çubuğunun görünür olmasını yeterince yavaşlatmak için sınıfının yönteminde
OnStartSearch
aşağıdaki satırın açıklamalarınıTestSearchTask
kaldırın:System.Threading.Thread.Sleep(100);
Çözümü yeniden oluşturup hata ayıklamaya başlayarak yeni ayarları test edin.
İlerleme çubuğu, her arama gerçekleştirdiğinizde arama penceresinde (arama metin kutusunun altında mavi bir çizgi olarak) görüntülenir.
Kullanıcıların aramalarını daraltmasını sağlamak için
Kullanıcıların Büyük/küçük harf eşleştir veya Tüm sözcüğü eşleştir gibi seçeneklerle aramalarını daraltmalarına izin vekleyebilirsiniz. Seçenekler, onay kutuları veya düğmeler olarak görünen komutlar olarak görünen boole olabilir. Bu kılavuzda bir boole seçeneği oluşturacaksınız.
TestSearch.cs dosyasında sınıfına
TestSearch
aşağıdaki kodu ekleyin. Kod, arama uygulamasınınSearchOptionsEnum
belirli bir seçeneğin açık veya kapalı olup olmadığını algılamasını sağlayan yöntemini geçersiz kılar. içindekiSearchOptionsEnum
kod, büyük/küçük harfle IVsEnumWindowSearchOptions numaralandırıcıyı eşleştirme seçeneği ekler. Büyük/küçük harf eşleştirme seçeneği de özelliği olarakMatchCaseOption
kullanılabilir hale getirilir.private IVsEnumWindowSearchOptions m_optionsEnum; public override IVsEnumWindowSearchOptions SearchOptionsEnum { get { if (m_optionsEnum == null) { List<IVsWindowSearchOption> list = new List<IVsWindowSearchOption>(); list.Add(this.MatchCaseOption); m_optionsEnum = new WindowSearchOptionEnumerator(list) as IVsEnumWindowSearchOptions; } return m_optionsEnum; } } private WindowSearchBooleanOption m_matchCaseOption; public WindowSearchBooleanOption MatchCaseOption { get { if (m_matchCaseOption == null) { m_matchCaseOption = new WindowSearchBooleanOption("Match case", "Match case", false); } return m_matchCaseOption; } }
TestSearchTask
sınıfında, yönteminde aşağıdaki satırın açıklamasını kaldırınOnStartSearch
:matchCase = m_toolWindow.MatchCaseOption.Value;
Şu seçeneği test edin:
Projeyi derleyin ve hata ayıklamaya başlayın. Deneysel örnek görüntülenir.
Araç penceresinde, metin kutusunun sağ tarafındaki Aşağı oku seçin.
Büyük /küçük harf eşleştir onay kutusu görüntülenir.
Büyük/küçük harf eşleştir onay kutusunu seçin ve bazı aramalar yapın.
Arama filtresi eklemek için
Kullanıcıların arama hedefleri kümesini daraltmasına olanak sağlayan arama filtreleri ekleyebilirsiniz. Örneğin, Dosya Gezgini dosyaları en son değiştirildikleri tarihlere ve dosya adı uzantılarına göre filtreleyebilirsiniz. Bu kılavuzda, yalnızca çift çizgiler için bir filtre ekleyeceksiniz. Kullanıcı bu filtreyi seçtiğinde, arama konağı belirttiğiniz dizeleri arama sorgusuna ekler. Ardından arama yönteminizin içinde bu dizeleri tanımlayabilir ve arama hedeflerini buna göre filtreleyebilirsiniz.
TestSearch.cs dosyasında sınıfına
TestSearch
aşağıdaki kodu ekleyin. Kod, arama sonuçlarını yalnızca çift satırların görünmesi için filtrelemeyi belirten bir WindowSearchSimpleFilter ekleyerek uygularSearchFiltersEnum
.public override IVsEnumWindowSearchFilters SearchFiltersEnum { get { List<IVsWindowSearchFilter> list = new List<IVsWindowSearchFilter>(); list.Add(new WindowSearchSimpleFilter("Search even lines only", "Search even lines only", "lines", "even")); return new WindowSearchFilterEnumerator(list) as IVsEnumWindowSearchFilters; } }
Şimdi arama denetimi arama filtresini
Search even lines only
görüntüler. Kullanıcı filtreyi seçtiğinde, dizelines:"even"
arama kutusunda görünür. Diğer arama ölçütleri filtreyle aynı anda görünebilir. Arama dizeleri filtreden önce, filtreden sonra veya her ikisi birden görünebilir.TestSearch.cs dosyasında, sınıfına
TestSearchTask
TestSearch
aşağıdaki yöntemleri ekleyin. Bu yöntemler, sonraki adımda değiştireceğiniz yöntemini desteklerOnStartSearch
.private string RemoveFromString(string origString, string stringToRemove) { int index = origString.IndexOf(stringToRemove); if (index == -1) return origString; else return (origString.Substring(0, index) + origString.Substring(index + stringToRemove.Length)).Trim(); } private string[] GetEvenItems(string[] contentArr) { int length = contentArr.Length / 2; string[] evenContentArr = new string[length]; int indexB = 0; for (int index = 1; index < contentArr.Length; index += 2) { evenContentArr[indexB] = contentArr[index]; indexB++; } return evenContentArr; }
TestSearchTask
sınıfında yöntemini aşağıdaki kodla güncelleştirinOnStartSearch
. Bu değişiklik, filtreyi destekleyecek şekilde kodu güncelleştirir.protected override void OnStartSearch() { // Use the original content of the text box as the target of the search. var separator = new string[] { Environment.NewLine }; string[] contentArr = ((TestSearchControl)m_toolWindow.Content).SearchContent.Split(separator, StringSplitOptions.None); // Get the search option. bool matchCase = false; matchCase = m_toolWindow.MatchCaseOption.Value; // Set variables that are used in the finally block. StringBuilder sb = new StringBuilder(""); uint resultCount = 0; this.ErrorCode = VSConstants.S_OK; try { string searchString = this.SearchQuery.SearchString; // If the search string contains the filter string, filter the content array. string filterString = "lines:\"even\""; if (this.SearchQuery.SearchString.Contains(filterString)) { // Retain only the even items in the array. contentArr = GetEvenItems(contentArr); // Remove 'lines:"even"' from the search string. searchString = RemoveFromString(searchString, filterString); } // Determine the results. uint progress = 0; foreach (string line in contentArr) { if (matchCase == true) { if (line.Contains(searchString)) { sb.AppendLine(line); resultCount++; } } else { if (line.ToLower().Contains(searchString.ToLower())) { sb.AppendLine(line); resultCount++; } } SearchCallback.ReportProgress(this, progress++, (uint)contentArr.GetLength(0)); // Uncomment the following line to demonstrate the progress bar. // System.Threading.Thread.Sleep(100); } } catch (Exception e) { this.ErrorCode = VSConstants.E_FAIL; } finally { ThreadHelper.Generic.Invoke(() => { ((TextBox)((TestSearchControl)m_toolWindow.Content).SearchResultsTextBox).Text = sb.ToString(); }); this.SearchResults = resultCount; } // Call the implementation of this method in the base class. // This sets the task status to complete and reports task completion. base.OnStartSearch(); }
Kodunuzu test edin.
Projeyi derleyin ve hata ayıklamaya başlayın. Visual Studio'nun deneysel örneğinde araç penceresini açın ve arama denetiminde Aşağı oku seçin.
Büyük /küçük harf eşleştir onay kutusu ve Yalnızca çift satır ara filtresi görüntülenir.
Filtreyi seçin.
Arama kutusu satırlar içerir :"çift", ve aşağıdaki sonuçlar görüntülenir:
2 iyi
4 İyi
6 Veda
Arama kutusundan silin
lines:"even"
, Büyük/küçük harf eşleştir onay kutusunu seçin ve arama kutusuna giring
.Aşağıdaki sonuçlar görüntülenir:
1 git
2 iyi
5 veda
Arama kutusunun sağ tarafındaki X işaretini seçin.
Arama temizlenir ve özgün içerik görüntülenir. Ancak Büyük/küçük harf eşleştir onay kutusu seçili durumdadır.