属性 returns 与设置的值不同
Property returns different value than what was set
我正在开发 Visual Studio 扩展,我当前的目标是在“工具”菜单中设置一个菜单项。单击此菜单项时,将打开一个 WinForms window,其中包含一个 ListView、3 个文本框和一个按钮。这个想法是,当您单击 ListView 中的其中一行时,该行的数据将填充到文本框中,以便您可以更新它。如果单击该按钮,将添加一个新行并清除文本框。但是,我在获取所选行的索引时遇到问题。
private int _index;
private void newSourceBtn_Click(object sender, EventArgs e)
{
// Add new row to the ListView
ListViewItem row = new ListViewItem();
row.SubItems.Add("new");
row.SubItems.Add(String.Empty);
row.SubItems.Add(String.Empty);
remoteSourceListView.Items.Add(row);
int index = remoteSourceListView.Items.Count - 1;
remoteSourceListView.Items[index].Selected = true;
newSourceAdded = true;
sourceNameTextBox.Clear();
sourceUrlTextBox.Clear();
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
remoteSourceListView.Items[IndexSelected].SubItems[1].Text = sourceNameTextBox.Text;
}
public void SourceURL_TextChanged(object sender, EventArgs e)
{
string url = sourceUrlTextBox.Text;
if ((url.StartsWith("http")) || (url.StartsWith("https")) || (url.StartsWith("git")))
{
sourceBranchTextBox.Enabled = true;
}
remoteSourceListView.Items[IndexSelected].SubItems[2].Text = url;
}
public void SourceBranch_TextChanged(object sender, EventArgs e)
{
}
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
IndexSelected = row.Index;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public int IndexSelected
{
get { return _index; }
set { _index = value; }
}
此代码显示将新行添加到 ListView 的按钮单击事件、更新 ListView 中行的每个文本框的文本更改事件(排序)以及 ListView 的选定索引更改事件这是我获取刚刚选择的行的索引的地方。在调试时,我注意到当我点击一行时,我在选定的索引更改事件中获得了正确的索引;但是,当我从任一文本更改事件中调用 IndexSelected 时,它总是给我一个不同的索引。
有什么建议吗?
从发布的代码中我找不到任何解释所记录行为的原因。
一个可能的原因可能是 insertion/deletion of new/existing ListViewItem 位于保存的 RowIndex 之前的位置。
然而,另一种方法是可行的。您可以尝试将全局 属性 设置为所选的 ListViewItem 并在需要设置其子项时重用该实例,而不是保留 RowIndex 。
如果 ListViewItems 的数量发生变化并且某些项目在保存的 RowIndex 之前 inserted/removed,则可以通过这种方式避免问题。但是,应提供防止空值的保护措施。
private ListViewItem CurrentItemSelected {get;set;}
......
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
CurrentItemSelected = row;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
if(CurrentItemSelected != null)
CurrentItemSelected.SubItems[1].Text = sourceNameTextBox.Text;
}
但是,我对你的代码有点困惑。您是否将 属性 MultiSelect
设置为 true?因为如果它设置为 false 那么您的代码就不需要循环。
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
if(remoteSourceListView.SelectedItems.Count > 0)
{
// With MultiSelect = false; there is only one selected item.
CurrentItemSelected = remoteSourceListView.SelectedItems[0];
sourceNameTextBox.Text = CurrentItemSelected.SubItems[1].Text;
sourceUrlTextBox.Text = CurrentItemSelected.SubItems[2].Text;
if (CurrentItemSelected.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = CurrentItemSelected.SubItems[3].Text;
}
}
}
我正在开发 Visual Studio 扩展,我当前的目标是在“工具”菜单中设置一个菜单项。单击此菜单项时,将打开一个 WinForms window,其中包含一个 ListView、3 个文本框和一个按钮。这个想法是,当您单击 ListView 中的其中一行时,该行的数据将填充到文本框中,以便您可以更新它。如果单击该按钮,将添加一个新行并清除文本框。但是,我在获取所选行的索引时遇到问题。
private int _index;
private void newSourceBtn_Click(object sender, EventArgs e)
{
// Add new row to the ListView
ListViewItem row = new ListViewItem();
row.SubItems.Add("new");
row.SubItems.Add(String.Empty);
row.SubItems.Add(String.Empty);
remoteSourceListView.Items.Add(row);
int index = remoteSourceListView.Items.Count - 1;
remoteSourceListView.Items[index].Selected = true;
newSourceAdded = true;
sourceNameTextBox.Clear();
sourceUrlTextBox.Clear();
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
remoteSourceListView.Items[IndexSelected].SubItems[1].Text = sourceNameTextBox.Text;
}
public void SourceURL_TextChanged(object sender, EventArgs e)
{
string url = sourceUrlTextBox.Text;
if ((url.StartsWith("http")) || (url.StartsWith("https")) || (url.StartsWith("git")))
{
sourceBranchTextBox.Enabled = true;
}
remoteSourceListView.Items[IndexSelected].SubItems[2].Text = url;
}
public void SourceBranch_TextChanged(object sender, EventArgs e)
{
}
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
IndexSelected = row.Index;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public int IndexSelected
{
get { return _index; }
set { _index = value; }
}
此代码显示将新行添加到 ListView 的按钮单击事件、更新 ListView 中行的每个文本框的文本更改事件(排序)以及 ListView 的选定索引更改事件这是我获取刚刚选择的行的索引的地方。在调试时,我注意到当我点击一行时,我在选定的索引更改事件中获得了正确的索引;但是,当我从任一文本更改事件中调用 IndexSelected 时,它总是给我一个不同的索引。
有什么建议吗?
从发布的代码中我找不到任何解释所记录行为的原因。
一个可能的原因可能是 insertion/deletion of new/existing ListViewItem 位于保存的 RowIndex 之前的位置。
然而,另一种方法是可行的。您可以尝试将全局 属性 设置为所选的 ListViewItem 并在需要设置其子项时重用该实例,而不是保留 RowIndex 。
如果 ListViewItems 的数量发生变化并且某些项目在保存的 RowIndex 之前 inserted/removed,则可以通过这种方式避免问题。但是,应提供防止空值的保护措施。
private ListViewItem CurrentItemSelected {get;set;}
......
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
ListView.SelectedListViewItemCollection selectedRows = remoteSourceListView.SelectedItems;
foreach (ListViewItem row in selectedRows)
{
sourceNameTextBox.Text = row.SubItems[1].Text;
sourceUrlTextBox.Text = row.SubItems[2].Text;
CurrentItemSelected = row;
if (row.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = row.SubItems[3].Text;
}
}
}
public void SourceName_TextChanged(object sender, EventArgs e)
{
if(CurrentItemSelected != null)
CurrentItemSelected.SubItems[1].Text = sourceNameTextBox.Text;
}
但是,我对你的代码有点困惑。您是否将 属性 MultiSelect
设置为 true?因为如果它设置为 false 那么您的代码就不需要循环。
public void SourcesListView_SelectedIndexChanged(object sender, EventArgs e)
{
if(remoteSourceListView.SelectedItems.Count > 0)
{
// With MultiSelect = false; there is only one selected item.
CurrentItemSelected = remoteSourceListView.SelectedItems[0];
sourceNameTextBox.Text = CurrentItemSelected.SubItems[1].Text;
sourceUrlTextBox.Text = CurrentItemSelected.SubItems[2].Text;
if (CurrentItemSelected.SubItems[3].Text != "")
{
sourceBranchTextBox.Enabled = true;
sourceBranchTextBox.Text = CurrentItemSelected.SubItems[3].Text;
}
}
}