溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

WPF中下拉框可作選擇項作為只讀文本框怎么使用

發(fā)布時間:2023-02-10 09:14:59 來源:億速云 閱讀:122 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“WPF中下拉框可作選擇項作為只讀文本框怎么使用”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    1、需求

    當(dāng)前在開發(fā)的系統(tǒng)需要一個這樣的控件。

    (1)可以選擇已有的選擇項,類似于ComboBox選擇;

    (2)可以通過其他按鈕點擊,選擇一個文件,選擇后,把文件路徑顯示到控件上,并且處于只讀狀態(tài),行為和只讀狀態(tài)下的TextBox保持一致。

    更直觀些,就是實現(xiàn)類似ArcMap中Toolbox中的數(shù)據(jù)集選擇下拉框,如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    該控件可以通過下拉的方式,選擇左側(cè)的圖層數(shù)據(jù),又可以通過點擊右側(cè)的打開文件按鈕,彈出打開文件對話框,選擇要設(shè)置的數(shù)據(jù)文件。該控件還可以通過鍵盤輸入,但我們的需求是禁止輸入,只能選擇和通過打開文件對話框設(shè)置。

    2、現(xiàn)有的ComboBox

    我計劃在WPF中的ComboBox控件的基礎(chǔ)上進行開發(fā),首先看通過簡單的屬性設(shè)置是否能夠滿足要求。

    (1)不設(shè)置任何參數(shù)

    在不設(shè)置任何參數(shù)的情況下,效果如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    可以顯示底圖上加載的數(shù)據(jù),但點擊【Select】按鈕,通過設(shè)置ComboBox.Text屬性,數(shù)據(jù)顯示不出來,這種效果離我們想要的還差十萬八千里。

    (2)設(shè)置ComboBox.IsEditable=true

    下面我們嘗試通過設(shè)置ComboBox的屬性看能不能達(dá)到我們想要的效果。首先把ComboBox.IsEditable屬性設(shè)置為true,然后測試下Text屬性設(shè)置后是否有效果了。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    目前可以把選擇的文件路徑設(shè)置到ComboBox.Text了,并且可以正常顯示,但鼠標(biāo)點上去,文本框的內(nèi)容可以修改,這不是我們想要的。于是發(fā)現(xiàn)ComboBox有個IsReadOnly屬性,把該屬性設(shè)置為true嘗試一下試試。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    目前下拉框中的內(nèi)容不能修改了,但實際操作的時候會發(fā)現(xiàn)有些別扭。當(dāng)鼠標(biāo)點擊下拉框,該控件得到焦點的時候,里面的文字默認(rèn)處于全選狀態(tài),此時想拖動鼠標(biāo),把文字拖動到尾部是操作不了的,只能再次點擊下拉框中的內(nèi)容,才可以和普通文本框的操作一樣通過鼠標(biāo)拖動視圖。

    經(jīng)過各種嘗試,發(fā)現(xiàn)當(dāng)ComboBox控件GotFocus的時候,里面的文字會默認(rèn)處于全選狀態(tài),這個我們需要解決一下。

    3、使用VisualTreeHelper單獨處理TextBox

    在網(wǎng)上查詢,發(fā)現(xiàn)ComboBox在IsEditable=true的狀態(tài)下,是有很多個控件組合而成的。如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    我們可以調(diào)用VisualTreeHelper,獲取這個TextBox,不過需要在Load后,再調(diào)用,不然這些控件是獲取不到的。

    this.Loaded += (x, y) =>
    {
        var myMainGrid = VisualTreeHelper.GetChild(this, 0);
        var myTextBox = VisualTreeHelper.GetChild(myMainGrid, 4) as TextBox;
        myTextBox.IsReadOnly = true;
        myTextBox.IsReadOnlyCaretVisible = true;
    };

    獲取TextBox后,我們需要解決ComboBox激活后,文字全選的問題。代碼如下。

    myTextBox.GotFocus += (m, n) =>
    {
        myTextBox.SelectionOpacity = 0;
        this._IsNeedClearSelection = true;
    };

    該代碼的的作用是當(dāng)TextBox得到焦點后,立刻把TextBox中文字選中的背景顏色的透明度設(shè)置為0,這樣操作者就感覺不出來文字被選中了。

    鼠標(biāo)左鍵彈起前,需要清空選中文字,并把光標(biāo)放到鼠標(biāo)點擊處,并還原文本選中的顏色,代碼如下。

    myTextBox.PreviewMouseLeftButtonUp += (m, n) =>
    {
        if (this._IsNeedClearSelection == false)
        {
            return;
        }
        var myPosition = n.GetPosition(myTextBox);
        int mySelectionStart = myTextBox.GetCharacterIndexFromPoint(myPosition, true);
        myTextBox.Select(mySelectionStart, 0);
        this._IsNeedClearSelection = false;
        myTextBox.SelectionOpacity = 0.4;
    };

    此時,基本上ComboBox能夠滿足我們的需求了,效果如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    但還有一個問題,就是在ComboBox在IsEditable=true的狀態(tài)下,鼠標(biāo)移動到可選項上的時候,選擇項不高亮了。為了解決這個問題,嘗試了很多方法,都不行,準(zhǔn)備放棄,就這樣了。

    因為系統(tǒng)使用了DEV for WPF UI庫,忽然想到了WPF DEV中的ComboBoxEdit,之前測試過,通過設(shè)置屬性,滿足不了需求。但沒有使用VisualTreeHelper深入的去測試,那就再嘗試下看看。

    4、使用WPF DEV中的ComboBoxEdit

    測試的時候,ComboBoxEdit在任何屬性都不設(shè)置的情況下,除了文字可以編輯,其他的都可以滿足要求。于是我設(shè)置IsReadOnly=True,但這個時候,下拉框中的可選擇項都處于不可用狀態(tài),也不能選擇,所以IsReadOnly屬性不能設(shè)置成True。嘗試了一下有可能性的其他屬性,例如EditMode等,都不能滿足需求。

    但在測試ComboBox的時候,知道了WPF的可視化樹這個概念,可以通過VisualTreeHelper獲取組成控件的子控件。于是加載后,在Load事件中,我們查看下ComboBoxEdit組織樹,如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    我看到了里面有個TextBox控件,這個就是顯示文本的控件了,感覺是不是獲取到這個TextBox后,把該TextBox設(shè)置成只讀是不是問題就完美解決了?

    這個樹比較深,我就找了一段根據(jù)類型獲取元素的代碼,如下圖所示。

    public static List<T> FindVisualChild<T>(DependencyObject pDependencyObject) where T : DependencyObject
    {
        List<T> myTList = new List<T> { };
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(pDependencyObject); i++)
        {
            DependencyObject myChild = VisualTreeHelper.GetChild(pDependencyObject, i);
            if (myChild != null && myChild is T myT)
            {
                myTList.Add(myT);
                List<T> myChildOfChildren = FindVisualChild<T>(myChild);
                if (myChildOfChildren != null)
                {
                    myTList.AddRange(myChildOfChildren);
                }
            }
            else
            {
                List<T> myChildOfChildren = FindVisualChild<T>(myChild);
                if (myChildOfChildren != null)
                {
                    myTList.AddRange(myChildOfChildren);
                }
            }
        }
        return myTList;
    }

    獲取TextBox和設(shè)置其屬性的代碼如下。

    public class DatasetComboBoxExUI : ComboBoxEdit
    {
        public DatasetComboBoxExUI()
        {
            this.Loaded += (x, y) =>
            {
                List<TextBox> myTextBoxList = VisualTreeExHelper.FindVisualChild<TextBox>(this);
                if (myTextBoxList.Count == 0)
                {
                    return;
                }
                var myTextBox = myTextBoxList[0];
                myTextBox.IsReadOnly = true;
                myTextBox.IsReadOnlyCaretVisible = true;
            };
        }
    }

    啟動測試,效果非常完美,正是我們需要的,界面如下圖所示。

    WPF中下拉框可作選擇項作為只讀文本框怎么使用

    “WPF中下拉框可作選擇項作為只讀文本框怎么使用”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    wpf
    AI