c#listview取消选择项目

我正在开发一个 Windows应用程序,它包含一个包含大量项目的ListView.
用户点击某个项目时,该应用会显示该项目的详细信息.该
用户然后有机会编辑这些细节.用户应该单击
每次更改后都会保存按钮,但当然并不总是会发生.

如果用户进行更改但未单击“保存”,则应用程序将显示一条消息
框询问他们是否愿意保存他们的更改.此框包含取消
按钮,如果他们点击取消,我想短路选择
一个项目并将用户保持在他们正在编辑的那个项目上.

我找不到这样做的方法,如果项目更改而不保存,我会显示itemselecedchanged事件中的对话框,如果用户单击取消,我从事件中删除我的功能并手动更改所选项目,之后我返回事件的功能,但在此之后,事件调用和我手动选择的项目未被选中.

private bool EnsureSelected()
    {
        bool continue_ = true;
        if (_objectChange)
        {
            var res = MessageBox.Show("Do you want to save changes?","Warning",MessageBoxButtons.YesNoCancel,MessageBoxIcon.Warning);
            switch (res)
            {
                case DialogResult.Cancel:
                    if (!string.IsNullOrEmpty(_selectedKey))
                    {
                        listView_Keys.ItemSelectionChanged -= listView_Keys_ItemSelectionChanged;
                        listView_Keys.Focus();
                        listView_Keys.Items[_selectedKey].Selected = true;
                        listView_Keys.ItemSelectionChanged += listView_Keys_ItemSelectionChanged;
                    }
                    continue_ = false;
                    break;
                case DialogResult.Yes:
                    button_Save.PerformClick();
                    _objectChange = false;
                    break;
                case DialogResult.No:
                    _objectChange = false;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }              
        }
        return continue_;
    }

更新::

我试过这个解决方案:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    private ListViewItem currentSelection = null;
    private bool pending_changes = false;
    private void listView1_ItemSelectionChanged(object sender,ListViewItemSelectionChangedEventArgs e)
    {
        if (e.Item == currentSelection)
        {
            // if the current Item gets unselected but there are pending changes
            if (!e.IsSelected && pending_changes)
            {
                var res = MessageBox.Show("Do you want to save changes?",MessageBoxIcon.Warning);
                switch (res)
                {
                    case DialogResult.Cancel:
                        // we dont want to change the selected item,so keep it selected
                        e.Item.Selected = true;
                        break;
                    case DialogResult.Yes:
                        //button_Save.PerformClick();
                        pending_changes = false;
                        break;
                    case DialogResult.No:
                        pending_changes = false;
                        break;
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }

        }
        else // not the selected button
        {
            if (!pending_changes && e.IsSelected)
            {
                // Item may be selected and we save it as the new current selection
                currentSelection = e.Item;
            }
            else if (pending_changes && e.IsSelected)
            {
                // Item may not be enabled,because there are pending changes
                e.Item.Selected = false;
            }
        }
    }

    private void Form1_Load(object sender,EventArgs e)
    {
        listView1.Items[0].Selected = true;
    }

    private void button1_Click(object sender,EventArgs e)
    {
        pending_changes = true;
    }
}

但是这没有用,第一次挂起的更改是真的,消息框调用了两次,第二次没有发生任何事情.

解决方法

首先,每当您选择另一个项目时,该事件应该触发两次.

首先取消选择的项目(其中e.IsSelected为false)

第二个是选中的项目(其中e.IsSelected为true)

假设您有一个设置的标志pending_changes,每当有未保存的更改时,下面的代码应该取消项目选择.

不幸的是,无论何时显示MessageBox,listView都会再次失去焦点.当您单击MessageBox时,焦点将返回到listView,这会导致控件再次触发其事件.这就是为什么需要一个肮脏的解决方法,需要记住我们在消息框上单击“取消”并再次对下一个事件执行操作.

以下是包含变通方法代码

private ListViewItem currentSelection = null;
private bool pending_changes = false;
private bool cancel_flag = false;
private void listView1_ItemSelectionChanged(object sender,ListViewItemSelectionChangedEventArgs e)
{
    Console.WriteLine("Item " + e.ItemIndex + " is Now " + e.IsSelected);
    if (e.Item != currentSelection)
    {
        // if another item gets selected but there are pending changes
        if (e.IsSelected && pending_changes)
        {
            if (cancel_flag)
            {
                // this handles the second mysterIoUs event
                cancel_flag = false;
                currentSelection.Selected = true;
                e.Item.Selected = false;
                return;
            }
            Console.WriteLine("uh oh. pending changes.");
            var res = MessageBox.Show("Do you want to save changes?",MessageBoxIcon.Warning);
            switch (res)
            {
                case DialogResult.Cancel:
                    // we dont want to change the selected item,so keep it selected
                    currentSelection.Selected = true;
                    e.Item.Selected = false;
                    // for some reason,we will get the same event with the same argments again,// after we click the cancel button,so remember our decision
                    cancel_flag = true;
                    break;
                case DialogResult.Yes:
                    // saving here. if possible without clicking the button,but by calling the method that is called to save
                    pending_changes = false;
                    currentSelection = e.Item;
                    break;
                case DialogResult.No:
                    pending_changes = false;
                    currentSelection = e.Item;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        else if (e.IsSelected && !pending_changes)
        {
            currentSelection = e.Item;
        }
    }
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...