2009-12-18 3 views
1

Ctrl-Left or Ctrl-Right을 사용하여 Windows Forms 응용 프로그램에서 콤보 상자의 선택된 값을 변경하려고 할 때 상황이 발생합니다. 그러나 콤보 상자가 양식의 선택된 컨트롤 인 경우에는 작동하지 않습니다. 선택한 값은 새 값으로 설정된 후 이전 값으로 설정됩니다. 콤보 상자가 선택된 컨트롤이 아니면 모든 것이 잘 동작합니다. 내 응용 프로그램에서는 마우스로 값을 변경할 수 있기 때문에 콤보가 포커스를받을 수 있습니다. 실제로 원하는 값을 변경하기 전에 양식에서 다른 컨트롤을 선택하여 원하는 결과를 얻을 수 있지만이 솔루션을별로 좋아하지 않습니다.C# 콤보 상자 선택한 인덱스가 변경되었습니다. 이전 값

두 가지 질문이 있습니다. 콤보 상자가 선택한 컨트롤 인 경우 selectedIndexChanged 이벤트가 이전 값으로 실행되는 이유는 무엇입니까? 어떻게 피할 수 있습니까? 아니면 좋은 해결 방법이 아닐 수 있습니까? 또한 내 문제를 설명하기위한 몇 가지 코드가 있습니다. 폼에 콤보 상자와 서식있는 텍스트 상자를 놓고 Form1.cs에서 아래 코드를 복사하면 내 문제가 발생할 수 있습니다. 당신은

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
     comboBox1.SelectedIndex = 0; 
    } 

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
     if (keyData == (Keys.Control | Keys.Left)) 
     { 
      DoUpdate(); 
     } 
     return base.ProcessCmdKey(ref msg, keyData); 
    } 

    private void DoUpdate() 
    { 
     int index = Convert.ToInt32(comboBox1.SelectedItem); 
     index++; 
     if (comboBox1.Focused) 
      richTextBox1.Select(); 
     comboBox1.SelectedItem = index.ToString(); 
    } 

    private void SetComboValue(int value) 
    { 
     comboBox1.SelectedItem = value.ToString(); 
     richTextBox1.AppendText(string.Format("Set value {0} \r\n", value.ToString()));   
    } 

    private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     richTextBox1.AppendText(string.Format("Selected index changed before {0}\r\n", comboBox1.SelectedItem)); 
     SetComboValue(Convert.ToInt32(comboBox1.SelectedItem)); 
     richTextBox1.AppendText(string.Format("Selected index changed after {0}\r\n", comboBox1.SelectedItem)); 
    } 
} 
+0

무엇 콤보 지수를 얻기 위해 appropiate의 메서드를 사용하는 방법에 대한 : selectedIndex의를. 그게 고칠 수 있니? – RvdK

답변

1

이것은 기본적으로 콤보 상자에 포커스가 있으면 컨트롤을 사용하지 않고 왼쪽 및 오른쪽을 누르면 값이 변경된다는 사실 때문에 발생합니다.

값을 증가시키면서 ctrl-left를 잡아 내고 키 입력을 기본 객체로 전달하면 왼쪽 키 누르기를 해석하고 선택된 항목을 감소시킵니다.

는 다음과 같이 코드를 변경

키 누름을 삼키는하고, 일이 예상대로 작동하는 것 :

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
     if (keyData == (Keys.Control | Keys.Left)) 
     { 
      DoUpdate(); 
      return true; 
     } 
     else 
     { 
      return base.ProcessCmdKey(ref msg, keyData); 
     } 
    } 
+0

당신은 끔찍한 권리가 있습니다 :-) 저는 Ctrl-Left에 너무 집중했습니다. 왼쪽 키와 오른쪽 키를 눌러 버렸다고 생각합니다. 이것도 드롭 다운 목록의 커서처럼 작동합니다. 그러나 지금 나는 질문이 : ProcessCmdKey 실제 값을 반환하는 경우이 키 조합을 ""이 키 "들어"아닌 다른 프로그램으로 전파 할 것입니다? 작은 응용 프로그램이 내 컴퓨터에 설치되어 있고 Ctrl-M을 누를 때이 작업을 수행하고 있지만 어떻게 든이 키 조합을 전파하지 않습니다. 결과적으로 VS의 Ctrl-M은이 특별한 경우에는 아무 것도하지 않습니다. – mosu

+0

다른 응용 프로그램이 듣고있을 때 어떤 동작이 될지 잘 모르겠지만 msdn은 다음과 같이 말합니다. "파생 클래스에서 ProcessCmdKey 메서드를 재정의하면 컨트롤에서 해당 키를 처리했음을 나타내려면 true를 반환해야합니다. 컨트롤에 의해 처리되지 않으면 기본 클래스의 ProcessCmdKey 메서드를 호출 한 결과를 반환해야합니다. " (http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey.aspx) ... 그래서 올바른 조치를 취하는 것 같아 ?? – rcknight

+0

Shift 키를 누른 채로 처리하면 사실을 반환하는 데 문제가되지 않습니다. 5 번 누르면 Windows StickyKeys 메시지가 나타나서 메시지가 더 보내 졌다고 생각합니다. 답장을 보내 주셔서 대단히 감사합니다. – mosu

0

왜 그냥 DoUpdate 방법에서 SetComboValue 방법을 실행하지 않는 (3 괜찮, 1, 2) DropDownList로 스타일 콤보를 만들 항목으로 몇 가지 숫자를 추가해야합니까? 그래도 작동하지 않는다면 DoUpdate 메소드에서 설정된 플래그를 설정하고 직접 액세스 할 때만 선택한 인덱스 변경 이벤트 만 실행할 수 있습니다. 그냥 생각.

우리는 폼을로드하는 동안 콤보 상자와 목록에 묶인 일련의 이벤트가있을 때 비슷한 작업을 수행합니다. 우리는 값을 설정하고로드 중에 이벤트가 실행되는 것을 원하지 않으므로 양식로드가 완료 될 때까지 이벤트가 계속 실행되지 않도록하는 플래그가 있습니다.

제 생각에는 값을 설정하고 있지만 다른 것이 선택 항목 변경 이벤트가 발생하도록 강제하는 것입니다. 그러나 DoUpdate 메서드와 SetComboValue 메서드에서 selectedindex를 설정 했으므로 무한 루프가 될 수있는 것처럼 보입니다.

선택한 색인을 한 곳에서 바꾸기 만하면됩니다.

+0

의견을 보내 주셔서 감사합니다. Joshua. SetComboValue에서이 줄이 있기 때문에 문제가 변경되지 않습니다. comboBox1.SelectedItem = value.ToString(); (실제로 그것은 comboBox1.SelectedItem = Convert.ToInt32 (value); 이지만 잘못되었으므로) selectedIndexChanged 이벤트를 한 번 더 트리거합니다. 그래서 값을 설정하는 메서드를 호출하더라도 값을 설정하더라도 동일한 문제가 있습니다. 디자인상의 이유로 SetComboValue를 호출하지 않습니다. 그 기능을 다른 방법으로 호출하는 것이 낫다고 생각합니다. – mosu

+0

나는 깃발로 행동 할 또 다른 전역 변수를 추가하는 것을 피하려고한다. 왜냐하면 나는 이미주의해야 할 깃발이 몇 개 있고, 내 경우에는 좋은 디자인이라고 생각하지 않기 때문이다. – mosu

관련 문제