2009-04-23 35 views
3

我有一个有制造商列表的组合框。当用户选择制造商时,下面的网格会填充所选制造商的数据。该数据可以修改。用户必须在完成所有更改后按下保存按钮。如何处理ComboBox选择的索引更改?

但用户可以忘记按保存并从ComboBox中选择另一个制造商,网格将填充另一个数据,因此以前的更改将会丢失。

所以我需要问用户他是否想在选择另一个制造商之前保存更改。

我该怎么做?或者,也许你提供了解决我的任务的另一种方式(从另一个角度来看)?

回答

3

您应该处理ComboBox.SelectedIndexChanged事件。喜欢的东西:

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

然后,每当它改变,你可以更新该功能的制造商信息ComboBox1_SelectedIndexChanged()将被调用。在填充新信息之前保存旧信息。或者在保存之前提示用户是否真的想要更改它。

+3

任何像e.Cancel为组合框选择变化? – IsmailS 2010-04-30 14:31:16

-2

ComboBox提供了一个名为SelectedIndexChanged的事件。无论何时PropertyIndexIndex发生变化,此事件都会引发,因此您必须处理该事件,以便每当用户想要更改组合索引时,如果用户未保存更改,请他这样做。

0

如果您想知道如何在选择更改时收到通知,则可以订阅ComboBox.SelectedIndexChanged事件。

如果您想要为用户提供保存选项,只有当某些内容发生变化并且她忘记保存更改时,您需要跟踪这些其他字段何时更改。这可以通过在用户编辑任何字段时保持布尔值被设置为true来完成。发生上述事件时,请在决定是否提供保存选项之前检查该值。

0

在这里做的最好的事情是比较已储存(在任何 - 在DataSet,列表对象等)在ComboBox(同样与其他领域)输入的数据,并检查是否有任何差异。这样,如果用户从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 2014-12-19 15:54:43

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

夜编码器的解决方案是优雅而简洁。我已经将它打包在一个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 

夜编码器的解决方案如下:

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开始工作真的很好,很简单,谢谢!我刚刚增加了在程序设计上避免使用messagebox的可能性 – 56ka 2013-11-15 16:25:09

1

一个简单保持t的方法未保存更改的机架。

加载任何原始值后,禁用“保存”按钮。

当用户试图离开时,检查是否启用了“保存”按钮。

根据需要启用或禁用“保存”按钮。

1

我知道这是一个较老的问题,但我想我会添加我使用的方法。我不确定它是否更好。应该有IndexChanging事件或可以取消的常规ComboBox中的某个事件。

该解决方案是@ AftabAhmedKalhoro's和@ 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 
相关问题