0

パスを含む必要がある編集可能な ComboBox があります。ユーザーは、ドロップダウン リストからいくつかの既定のパスを選択 (または独自のパスを入力) できます%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\ (All Users)。ドロップダウン リストの項目には(All Users)、前の例の部分のように簡単な説明が含まれています。そのようなアイテムを選択すると、この説明を削除して、有効なパスが ComboBox に表示されるようにします。

Text現在、文字列から説明を取り除き、ComboBoxのプロパティを設定してテキストを変更しようとしています。しかし、これは機能しません。文字列は正しく解析されますが、表示されるテキストは更新されません (ドロップダウン リストと同じままで、説明が表示されます)。

private void combobox_TextChanged(object sender, EventArgs e) {
            //..             

               string destPath = combobox.GetItemText(combobox.SelectedItem);                  
               destPath = destPath.Replace("(All Users)", "");                   
               destPath.Trim();                   
               combobox.Text = destPath; 

            //..
}
4

5 に答える 5

1

とそのPathEntry両方を格納するクラスを作成することをお勧めします。PathDescription

public sealed class PathEntry
{
    public string Path { get; private set; }
    public string Description { get; private set; }

    public PathEntry(string path)
      : this(path, path)
    {
    }

    public PathEntry(string path, string description)
    {
        this.Path = path;
        this.Description = description;
    }
}

次に、のインスタンスを作成して、BindingList<PathEntry>すべての既知のパスと説明を保存します。後で、ユーザー定義のパスを追加できます。

private readonly BindingList<PathEntry> m_knownPaths =
  new BindingList<PathEntry>();

そして、フォームのコンストラクターを次のように更新します。

public YourForm()
{
    InitializeComponent();

    m_knownPaths.Add(new PathEntry("%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs",
      "(All Users)"));
    // TODO: add other known paths here

    combobox.ValueMember = "Path";
    combobox.DisplayMember = "Description";
    combobox.DataSource = m_knownPaths;

}

private void combobox_DropDown(object sender, EventArgs e)
{
    combobox.DisplayMember = "Description";
}

private void combobox_DropDownClosed(object sender, EventArgs e)
{
    combobox.DisplayMember = "Path";
}

あなたはもっとたくさんのことを学びたいと思うかもしれませんDataSourceDisplayMemberそしてValueMemberMSDNから。

于 2012-10-10T17:34:17.413 に答える
1

BeginInvoke() を使用して、同様の質問で解決策を見つけました

ニコライのソリューションを使用すると、私の方法は次のようになります。

private void combobox_SelectedIndexChanged(object sender, EventArgs e) {
            if (combobox.SelectedIndex != -1) {
                //Workaround (see below)
                var x = this.Handle;
                this.BeginInvoke((MethodInvoker)delegate { combobox.Text = combobox.SelectedValue.ToString(); });                  
            }
}

BeginInvoke ではコントロールをロードまたは表示する必要があるため、回避策が必要です。これは、プログラムが開始されたばかりの場合は必ずしもそうではありません。hereから取得しました。

于 2012-10-11T10:25:33.703 に答える
1

これはおそらく最も洗練された解決策ではありませんが、私のように、InvokeMethods をもう少しよく理解するまでは使いたくない初心者向けの簡単な解決策です。

新しい文字列 (オブジェクト) を Items 配列内の位置に割り当てると、ハンドラーが再帰的に再起動されるため、ブール値が必要です。

私はまったく同じ問題に取り組んでいたので、今これを理解しました。

共有するだけです:)

    bool preventDoubleChange = false;
    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (preventDoubleChange){
            preventDoubleChange = false;
            return;
        }

        preventDoubleChange = true;

        switch (comboBox1.SelectedIndex)
        {
            case 0:
                comboBox1.Items[0] = "ChangeToThisText";
                break;
            case 1:
                comboBox1.Items[1] = "ChangeToThisText";
                break;
            default:
                preventDoubleChange = false;
                break;
        }            
    }

...または、「タグ」フィールドの使用に慣れている場合は、ブール値の混乱を避けることができます。私の意見では、この 2 番目のバリエーションもよりクリーンです。

    public Form1()
    {
        InitializeComponent();

        comboBox1.Items.Add("Item One");                        //Index 0
        comboBox1.Items.Add("Item Two");                        //Index 1
        comboBox1.Items.Add("Item Three");                             //Index 2
        comboBox1.Items.Add("Item Four");                       //Index 3
    }

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (comboBox1.Tag != null && (int)comboBox1.Tag == comboBox1.SelectedIndex)
            return;

        switch (comboBox1.SelectedIndex)
        {
            case 0:
                break;
            case 1:
                comboBox1.Tag = comboBox1.SelectedIndex;
                comboBox1.Items[comboBox1.SelectedIndex] = "changed item 2";
                break;
            case 2:
                comboBox1.Tag = comboBox1.SelectedIndex;
                comboBox1.Items[comboBox1.SelectedIndex] = "changed item 3";
                break;
            case 3:
                break;
            default:
                break;
        }
    }
于 2013-06-20T11:59:34.157 に答える
0

レッドファルコン、

この方法でテキストを変更することはできません。あなたがする必要があるのは、selectedindex値を取得してから、Textプロパティを設定することです。そんな感じ:

 protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
    {
        var index = DropDownList1.SelectedIndex;

        DropDownList1.Items[index].Text = "changed";
    }
于 2012-10-10T17:06:42.230 に答える
0

` private voidombobox_TextChanged(object sender, EventArgs e) { //..

           string destPath = combobox.SelectedItem.Text;                  
           destPath = destPath.Replace("(All Users)", "");                   
           destPath.Trim();                   
           combobox.SelectedItem.Text = destPath; 

        //..

} `

于 2012-10-10T17:16:38.763 に答える