2009-04-23 1 views
3

У меня есть ComboBox, у которого есть список производителей. Когда пользователь выбирает производителя, сетка ниже заполняется данными для выбранного производителя. Эти данные могут быть изменены. Пользователь должен нажать кнопку «Сохранить» после выполнения всех изменений.Как я могу обработать выбранный индекс ComboBox?

Но пользователь может забыть нажать «Сохранить» и выбрать другого производителя из ComboBox, и сетка будет заполнена другими данными, поэтому предыдущие изменения будут потеряны.

Поэтому мне нужно спросить пользователя, хочет ли он сохранить изменения, прежде чем выбирать другого производителя.

Как я могу это сделать? Или, может быть, вы предлагаете другой способ решения моей задачи (глядя под другим углом)?

ответ

3

Вы должны обработать событие ComboBox.SelectedIndexChanged. Что-то вроде:

this.ComboBox1.SelectedIndexChanged += new system.EventHandler(ComboBox1_SelectedIndexChanged); 

Тогда ComboBox1_SelectedIndexChanged() будет вызываться всякий раз, когда она меняется, и вы можете обновить информацию производителя в этой функции. Сохраните старую информацию перед заполнением новой информации. Или попросите пользователя, действительно ли они хотят изменить его перед сохранением.

+3

Все как e.Cancel для изменения выбора COMBOBOX? – IsmailS

-2

ComboBox предоставляет событие под названием SelectedIndexChanged. Это событие возникает всякий раз, когда свойство SelectedIndex изменяется, поэтому вам нужно обрабатывать событие для, когда пользователь хочет изменить индекс комбо, если пользователь не сохранил изменения, попросите его сделать это.

0

Если вам интересно, как вы можете получать уведомление при изменении выбора, вы можете подписаться на событие ComboBox.SelectedIndexChanged.

Если вы хотите предложить пользователю возможность сохранить, только когда что-то изменилось, и она забыли, чтобы сохранить изменения, вам нужно отслеживать, когда эти другие поля меняются. Это может быть достигнуто путем сохранения логического значения, которое присваивается true, когда пользователь редактирует любые поля. Когда произойдет указанное событие, проверьте это значение, прежде чем принимать решение о том, следует ли предлагать вариант сохранения.

0

Лучше всего здесь сравнить данные, введенные в ComboBox (аналогично другим полям), уже сохраненным (в любом случае - DataSet, объекту списка и т. Д.) И проверить любые различия. Таким образом, если пользователь выбирает другой элемент из ComboBox, но затем изменяет его на исходный, программа распознает, что данные все еще остались , а не. (Например, обработка события SelectionChangeCommited и установка логического значения до true не позволили бы этому обнаружить и дополнительно было бы сложнее реализовать). В этой ситуации простейший и изящный подход, похоже, также обеспечит лучшая функциональность.

9

Вот как мы можем создать подкласс ComboBox, чтобы ввести новый SelectedIndexChangingEvent с возможностью отменить изменение:

public class ComboBoxEx : ComboBox 
{ 
    public event CancelEventHandler SelectedIndexChanging; 

    [Browsable(false)] 
    public int LastAcceptedSelectedIndex { get; private set; } 

    public ComboBoxEx() 
    { 
     LastAcceptedSelectedIndex = -1; 
    } 

    protected void OnSelectedIndexChanging(CancelEventArgs e) 
    { 
     var selectedIndexChanging = SelectedIndexChanging; 
     if (selectedIndexChanging != null) 
      selectedIndexChanging(this, e); 
    } 


    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
     if (LastAcceptedSelectedIndex != SelectedIndex) 
     { 
      var cancelEventArgs = new CancelEventArgs(); 
      OnSelectedIndexChanging(cancelEventArgs); 

      if (!cancelEventArgs.Cancel) 
      { 
       LastAcceptedSelectedIndex = SelectedIndex; 
       base.OnSelectedIndexChanged(e); 
      } 
      else 
       SelectedIndex = LastAcceptedSelectedIndex; 
     } 
    } 

} 
+0

^** Это фактический ответ. ** – CodeAngry

0

Большой nightcoder работу. Ваш код работает отлично.

Спасибо!

Для разработчиков, которые пишут в VB.NET здесь у вас есть перевод: решение

Imports System.ComponentModel 

Public Class ComboBoxEx 
    Inherits ComboBox 

    Private pLastAcceptedSelectedIndex As Integer 

    Public Event SelectedIndexChanging As CancelEventHandler 

    Public Property LastAcceptedSelectedIndex() As Integer 
    Get 
     Return pLastAcceptedSelectedIndex 
    End Get 
    Set(ByVal value As Integer) 
     pLastAcceptedSelectedIndex = value 
    End Set 
    End Property 

    Public Sub New() 
    LastAcceptedSelectedIndex = -1 
    End Sub 

    Protected Sub OnSelectedIndexChanging(ByVal e As CancelEventArgs) 
    RaiseEvent SelectedIndexChanging(Me, e) 
    End Sub 

    Protected Overrides Sub OnSelectedIndexChanged(ByVal e As System.EventArgs) 
    If LastAcceptedSelectedIndex <> SelectedIndex Then 
     Dim cancelEventArgs As CancelEventArgs 

     cancelEventArgs = New CancelEventArgs() 
     OnSelectedIndexChanging(cancelEventArgs) 

     If Not cancelEventArgs.Cancel Then 
     LastAcceptedSelectedIndex = SelectedIndex 
     MyBase.OnSelectedIndexChanged(e) 
     Else 
     SelectedIndex = LastAcceptedSelectedIndex 
     End If 
    End If 
    End Sub 
End Class 
1

Night Coder является элегантным и лаконичным. Я упаковал его в dll.
(Я называю это CustomControls.) Для этого создайте новую библиотеку классов и добавьте первые несколько операторов в решение Night Coder (скопированное здесь как удобство).

После того как вы скомпилировали код, вы можете добавить его в качестве ссылки. Я фактически загрузил dll в мою панель инструментов Visual Studio. Таким образом, я могу перетащить элемент управления на мою форму во время разработки. Удобно, новое событие появляется в списке свойств.

use System.ComponentModel; 

use System.Windows.Forms; //this will need to be added as a reference 

//your namespace will name your dll call it what you will 

namespace CustomControls 

решение Night для Coder следующим образом:

public class ComboBoxEx : ComboBox 
{ 
     public event CancelEventHandler SelectedIndexChanging; 


    [Browsable(false)] 
    public int LastAcceptedSelectedIndex { get; private set; } 

    public ComboBoxEx() 
    { 
      LastAcceptedSelectedIndex = -1; 
    } 

    protected void OnSelectedIndexChanging(CancelEventArgs e) 
    { 
      var selectedIndexChanging = SelectedIndexChanging; 
      if (selectedIndexChanging != null) 
        selectedIndexChanging(this, e); 
    } 


    protected override void OnSelectedIndexChanged(EventArgs e) 
    { 
      if (LastAcceptedSelectedIndex != SelectedIndex) 
      { 
        var cancelEventArgs = new CancelEventArgs(); 
        OnSelectedIndexChanging(cancelEventArgs); 

        if (!cancelEventArgs.Cancel) 
        { 
          LastAcceptedSelectedIndex = SelectedIndex; 
          base.OnSelectedIndexChanged(e); 
        } 
        else 
          SelectedIndex = LastAcceptedSelectedIndex; 
      } 
    } 
} 
4

Создать 2 переменные уровня класса

private bool selectionCancelled=false; 
private int lastSelectedIndex=-1; 

Тогда в SelectedIndex случае вы можете написать код следующим образом

 if (!selectionCancelled) 
     { 
      if (MessageBox.Show("Are you sure you want to change the selection ?", this.Text, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No) 
      { 
       selectionCancelled = true; 
       comboBox.SelectedIndex = lastSelectedIndex; 
       return; 
      } 

      lastSelectedIndex = comboBox.SelectedIndex; 
      // Normal code of the event handler 

     } 
     else 
     { 

      selectionCancelled = false; 
     } 
+0

Работает с '.NET framework 2.0' Действительно хорошо и просто, спасибо! Я только что добавил возможность избежать сообщения с программным назначением – 56ka

1

легкий способ сохранить t стойка несохраненных изменений.

После загрузки любых исходных значений отключите кнопку «Сохранить».

Когда пользователь пытается уйти, проверьте, включена ли кнопка «Сохранить».

Включите или отключите кнопку «Сохранить» при необходимости.

1

Я знаю, что это старый вопрос, но я думал, что добавлю метод, который использовал. Я не уверен, что это лучше. Должно быть событие IndexChanging или что-то в обычном ComboBox, которое можно отменить.

Решение представляет собой комбинацию сообщений @ AftabAhmedKalhoro и @ jeffamaphone, но вместо этого использует свойство Tag.

Я не хотел подклассифицировать ComboBox или иметь какие-либо дополнительные частные переменные, плавающие в форме. Но некоторым может не понравиться свойство Tag, потому что оно скрыто, если вы не используете его (вид слева от VB6).

Private Sub MainForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
    ComboBox1.Items.Add("Item1") 
    ComboBox1.Items.Add("Item2") 
    ComboBox1.Items.Add("Item3") 
    ComboBox1.Items.Add("Item4") 
    ' Load Value from database or whatever and set the value or index. 
    ComboBox1.SelectedIndex = 0 
    ComboBox1.Tag = ComboBox1.SelectedIndex 

    ' I add the handler at the end because I don't want it to fire during loading the form. 
    AddHandler ComboBox1.SelectedIndexChanged, New EventHandler(AddressOf ComboBox1_SelectedIndexChanged) 
End Sub 

Private Sub ComboBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) 
    If (ComboBox1.Tag <> ComboBox1.SelectedIndex) Then 
     If MessageBox.Show("Warning! You are changing the index." & vbCrLf & _ 
          "Do you wish to continue?", _ 
          "Changing Index", _ 
          MessageBoxButtons.YesNo, _ 
          MessageBoxIcon.Warning) = Windows.Forms.DialogResult.Yes Then 
      ComboBox1.Tag = ComboBox1.SelectedIndex 
      ' Do Something. 
     Else 
      ComboBox1.SelectedIndex = ComboBox1.Tag 
     End If 
    End If 
End Sub 

Обратите внимание, что сброс SelectedIndex вызовет событие снова огонь в этой линии:

ComboBox1.SelectedIndex = ComboBox1.Tag 

 Смежные вопросы

  • Нет связанных вопросов^_^