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:

  1. VSPackage projesi oluşturma.

  2. Salt okunur TextBox ile UserControl içeren bir araç penceresi oluşturun.

  3. Araç penceresine bir arama kutusu ekleyin.

  4. Arama uygulamasını ekleyin.

  5. bir ilerleme çubuğunun anlık aramasını ve görüntülenmesini etkinleştirin.

  6. Büyük /küçük harf eşleştir seçeneği ekleyin.

  7. Yalnızca Çift satır ara filtresi ekleyin.

VSIX projesi oluşturmak için

  1. 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

  1. Projede TestToolWindowSearch TestSearchControl.xaml dosyasını açın.

  2. 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>
    
  3. TestSearchControl.xaml.cs dosyasına aşağıdaki using yönergesini ekleyin:

    using System.Text;
    
  4. 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();
        }
    }
    
  5. Projeyi derleyin ve hata ayıklamaya başlayın. Visual Studio'nun deneysel örneği görüntülenir.

  6. 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

  1. TestSearch.cs dosyasında sınıfına TestSearch aşağıdaki kodu ekleyin. Kod, get erişimcisinin SearchEnabled döndürebilmesi trueiç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; }
    }
    
  2. Projeyi derleyin ve hata ayıklamaya başlayın. Deneysel örnek görüntülenir.

  3. 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.

  1. 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;
    
  2. 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 TestSearchTaskoluş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;
        }
    }
    
  3. Aşağıdaki adımları gerçekleştirerek arama uygulamanızı test edin:

    1. Projeyi yeniden derleyin ve hata ayıklamayı başlatın.

    2. 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.

  1. * 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ındaki ProvideSearchSettings 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);}
    
  2. Çö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.

  3. 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ın TestSearchTask :

    SearchCallback.ReportProgress(this, progress++, (uint)contentArr.GetLength(0));
    
  4. İ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);
    
  5. Çö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.

  1. TestSearch.cs dosyasında sınıfına TestSearch aşağıdaki kodu ekleyin. Kod, arama uygulamasının SearchOptionsEnum belirli bir seçeneğin açık veya kapalı olup olmadığını algılamasını sağlayan yöntemini geçersiz kılar. içindeki SearchOptionsEnum 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 olarak MatchCaseOption 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;
        }
    }
    
  2. TestSearchTask sınıfında, yönteminde aşağıdaki satırın açıklamasını kaldırınOnStartSearch:

    matchCase = m_toolWindow.MatchCaseOption.Value;
    
  3. Şu seçeneği test edin:

    1. Projeyi derleyin ve hata ayıklamaya başlayın. Deneysel örnek görüntülenir.

    2. 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.

    3. 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.

  1. 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 onlygörüntüler. Kullanıcı filtreyi seçtiğinde, dize lines:"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.

  2. 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 destekler OnStartSearch .

    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;
    }
    
  3. 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();
    }
    
  4. Kodunuzu test edin.

  5. 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.

  6. 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

  7. Arama kutusundan silinlines:"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

  8. 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.