Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如何处理组合框所选索引的更改?_.net_Winforms_Combobox - Fatal编程技术网

.net 如何处理组合框所选索引的更改?

.net 如何处理组合框所选索引的更改?,.net,winforms,combobox,.net,Winforms,Combobox,我有一个组合框,其中有一个制造商列表。当用户选择制造商时,下面的网格将填充所选制造商的数据。这些数据可以修改。所有更改完成后,用户必须按下保存按钮 但是用户可能会忘记按Save键并从组合框中选择其他制造商,网格将填充其他数据,因此以前的更改将丢失 所以我需要询问用户在选择其他制造商之前是否希望保存更改 我该怎么做?或者您提供了另一种解决我的任务的方法(从另一个角度看)?您应该处理ComboBox.SelectedIndexChanged事件。比如: this.ComboBox1.Selected

我有一个组合框,其中有一个制造商列表。当用户选择制造商时,下面的网格将填充所选制造商的数据。这些数据可以修改。所有更改完成后,用户必须按下保存按钮

但是用户可能会忘记按Save键并从组合框中选择其他制造商,网格将填充其他数据,因此以前的更改将丢失

所以我需要询问用户在选择其他制造商之前是否希望保存更改


我该怎么做?或者您提供了另一种解决我的任务的方法(从另一个角度看)?

您应该处理ComboBox.SelectedIndexChanged事件。比如:

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

然后,无论何时更改,都会调用
ComboBox1\u SelectedIndexChanged()
,您可以在该函数中更新制造商信息。在填充新信息之前保存旧信息。或者,如果用户确实想在保存前更改,则提示用户。

组合框提供一个名为SelectedIndexChanged的事件。每当属性SelectedIndex更改时,此事件就会引发,因此您必须处理此事件,每当用户想要更改组合的索引时,如果用户尚未保存更改,请让他这样做。

如果您不知道如何在选择更改时收到通知,您可以订阅此事件


如果您想向用户提供保存选项,仅当某些内容发生更改并且用户忘记保存更改时,您需要跟踪这些其他字段的更改时间。这可以通过维护一个布尔值来实现,该布尔值在用户编辑任何字段时设置为true。当发生上述事件时,在决定是否提供保存选项之前,请检查此值。

这里最好的做法是将在
组合框中输入的数据(与其他字段类似)与已存储的数据(在任何位置-数据集、列表对象等)进行比较,并检查是否存在任何差异。这样,如果用户从组合框中选择另一项,然后将其更改回原始项,则程序会识别出数据尚未修改。(例如,处理事件,并将布尔值设置为
true
,将不允许检测到此情况,并且将更难实现。)在这种情况下,最简单、最优雅的方法似乎也能提供最好的功能。

下面是我们如何将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;
        }
    }

}

干得好,夜猫子。你的代码工作得很好

谢谢

对于在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
导入System.ComponentModel
公共类ComboBox
继承组合框
私有pLastAcceptedSelectedIndex为整数
公共事件SelectedIndex更改为CancelEventHandler
公共属性LastAcceptedSelectedIndex()为整数
得到
返回pLastAcceptedSelectedIndex
结束
设置(ByVal值为整数)
pLastAcceptedSelectedIndex=值
端集
端属性
公共分新()
LastAcceptedSelectedIndex=-1
端接头
选定索引更改时受保护的子项(通过值e作为CancelEventArgs)
RaiseEvent Selected索引更改(Me,e)
端接头
已更改选定索引的受保护覆盖子项(通过值e作为System.EventArgs)
如果LastAcceptedSelectedIndex SelectedIndex,则
Dim cancelEventArgs作为cancelEventArgs
cancelEventArgs=新的cancelEventArgs()
OnSelectedIndexChangeing(取消事件参数)
如果不是cancelEventArgs。则取消
LastAcceptedSelectedIndex=SelectedIndex
MyBase.OnSelectedIndexChanged(e)
其他的
SelectedIndex=LastAcceptedSelectedIndex
如果结束
如果结束
端接头
末级

夜间编码器的解决方案优雅简洁。我已将其打包在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;
            }
    }
}

创建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;
        }

跟踪未保存更改的简单方法

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

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


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

我知道这是一个较老的问题,但我想我应该添加我使用的方法。我不知道是否更好。应该有一个
indexchange
事件,或者在常规的
组合框中可以取消的某个事件

解决方案是结合@AftabAhmedKalhoro和@jeffamaphone的帖子,但使用
标签
属性

我不想将
组合框
分为子类,也不想让任何额外的私有变量在表单中浮动。但是有些人可能不喜欢
标记
属性,因为如果您不习惯使用它,它有点隐藏(有点像VB6遗留下来的)


任何类似于e.取消组合框选择更改的功能?自
.NET framework 2.0
以来一直有效,非常好而且简单,谢谢!我刚刚添加了在程序分配上避免messagebox的可能性,这是实际的答案。
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
ComboBox1.SelectedIndex = ComboBox1.Tag