2009-04-23 7 views
3

私はメーカーのリストを持つComboBoxを持っています。ユーザがメーカを選択すると、下のグリッドには選択されたメーカのデータが入力されます。そのデータは変更できます。すべての変更が完了したら、ユーザーは[保存]ボタンを押す必要があります。選択したComboBoxのインデックスを変更する方法を教えてください。

しかし、ユーザーは[保存]を押してコンボボックスから別のメーカーを選択することを忘れることがあり、グリッドに別のデータが入力されるため、以前の変更は失われます。

他のメーカーを選択する前に変更を保存するかどうかをユーザーに尋ねる必要があります。

どうすればいいですか?あるいは、別の角度から見て私の仕事を解決する別の方法を提供しているかもしれませんか?

答えて

3

ComboBox.SelectedIndexChangedイベントを処理する必要があります。ような何か:それは変更されるたびに

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

はその後ComboBox1_SelectedIndexChanged()が呼び出されると、あなたはその関数で、製造元の情報を更新することができます。新しい情報を入力する前に古い情報を保存してください。または、保存する前に実際に変更したい場合は、ユーザーにプロンプ​​トを出します。

+3

コンボボックスの選択の変更のためのe.Cancelようなもの? – IsmailS

-2

ComboBoxは、SelectedIndexChangedというイベントを提供します。このイベントは、SelectedIndexプロパティが変更されるたびに発生し、イベントを処理する必要があります。ユーザーがコンボのインデックスを変更したいときはいつでも、ユーザーが変更を保存していない場合は、

0

選択が変更されたときに通知を受信する方法が不明な場合は、ComboBox.SelectedIndexChangedイベントに登録することができます。

変更を保存するオプションをユーザーに提供したい場合は、何か変更があったときに変更内容を保存することを忘れてしまった場合にのみ、これらのフィールドがいつ変わるかを把握する必要があります。これは、ユーザーがフィールドを編集するたびに真に設定されるブール値を維持することによって達成できます。上記のイベントが発生した場合は、保存するかどうかを決定する前にこの値を確認してください。

0

ComboBoxに入力されたデータ(他のフィールドと同様)と既に格納されているデータ(DataSet、リストオブジェクトなど)とを比較して違いがないかどうかを確認するのが最も良い方法です。この方法で、ユーザーがComboBoxから別の項目を選択して元の項目に戻すと、プログラムはではなく、のデータがまだ変更されていることを認識します。 (たとえば、SelectionChangeCommitedイベントを処理し、ブール値をtrueに設定すると、これが検出されず、さらに実装するのが少し難しくなります)。この状況では、最も簡単で最も洗練されたアプローチでも、最高の機能性。

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

} 
9

たちは変化をキャンセルする可能性を持つ新しいSelectedIndexChangingEventを紹介するコンボボックスをサブクラス化する方法です。あなたのコードは完全に動作します。

ありがとうございます!あなたが翻訳を持ってここに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 
+0

^**これは実際の回答です。** – CodeAngry

0

グレートジョブnightcoder:ここ

1

ナイトコーダーのソリューションは、エレガントかつ簡潔です。私はdllにパッケージ化しました。
(私はそれをCustomControlsと呼んでいます)。これを行うには、新しいクラスライブラリを作成し、最初のいくつかのステートメントをNight Coderのソリューションに追加します。

コードをコンパイルしたら、参照として追加できます。私は実際にVisual Studio Toolsペインにdllをロードしました。そうすれば、設計時にコントロールをフォームにドラッグできます。都合の良いことに、新しいイベントがプロパティリストに表示されます。

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」以降に動作します。本当にうまく簡単です。ありがとうございます!私はちょうどプログラマティックな割り当てにメッセージボックスを避ける可能性を追加しました – 56ka

1

アン簡単に次のようなコードを書くことができますtを保つ方法未保存の変更のラック。

元の値をロードしたら、[保存]ボタンを無効にします。

ユーザーが離脱しようとすると、[保存]ボタンが有効になっているかどうかを確認します。

必要に応じて[保存]ボタンを有効または無効にします。

1

これは古い質問ですが、私が使用した方法を追加すると思いました。それが良いかどうかは分かりません。 ComboBoxには、IndexChangingのイベントや何かがありますが、これは取り消すことができます。

解決策は@ 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