当 Form.AutoScroll=true 时,PropertyGrid 会导致意外滚动
PropertyGrid causes unintended scrolling when Form.AutoScroll=true
我的 .NET Forms 应用程序中的 PropertyGrid 控件出现问题。
我尝试在 AutoScroll 属性 设置为 true 的表单上放置一个 ProperyGrid。
当PropertyGrid位于Form的显示区域内时,就OK了。
但是,当 PropertyGrid 位于 Form 的显示区域之外时,PropertyGrid 会导致意外滚动。
我很难用文字描述这个问题。
这是重现此问题的代码。
using System.Drawing;
using System.Windows.Forms;
namespace PropertyGridAutoScrollProblem
{
public partial class Form1 : Form
{
public Form1()
{
//InitializeComponent();
Control[] controls = new Control[]
{
new TextBox(),
new RadioButton(),
new ListBox(),
new ListView(),
new PropertyGrid() { SelectedObject = this },
new DataGridView(),
};
var tabControl = new TabControl();
tabControl.Size = new Size(400, 400);
tabControl.Location = new Point(50, 50);
this.Controls.Add(tabControl);
foreach (var control in controls)
{
control.Location = new Point(50, 250);
control.Size = new Size(200, 100);
var tabPage = new TabPage(control.GetType().Name);
tabPage.Controls.Add(control);
tabControl.Controls.Add(tabPage);
}
this.AutoScroll = true;
this.ClientSize = new Size(400, 200);
}
}
}
这个程序有一些标签。
每个选项卡包含一个与其选项卡名称相关且位于窗体显示区域之外的控件。
如果您单击 "PropertyGrid" 以外的任何选项卡,则不会发生滚动。
但是,如果您单击 "PropertyGrid" 选项卡,则会发生意外滚动。
These are the screenshots of this program.
最后一个(右下角)屏幕截图是在单击 "PropertyGrid" 之后。
有什么方法可以避免意外滚动吗?
更新 1:
Here is the screenshots I tried and expected.
更新2:
@RezaAghaei 谢谢你的解决方案,但它对我来说并不完美..
我的预期结果是 "no scrolling occurred"。
Here is the screenshots I tried and expected.
更新3:
@RezaAghaei 谢谢你的回复。
据我了解,当我们取消select 表单并再次select 时,表单会滚动以通过 AutoScroll 默认行为显示焦点控件的左上角坐标。
而且,如果我单击第二个选项卡,选项卡控件将获得焦点。
我觉得这对我来说很自然。
如果我在 select 选项卡后单击选项卡页面上的任何控件,单击的控件将获得焦点,而选项卡控件将失去焦点。
在这种情况下,如果我 deselect 表单并再次 select ,表单将滚动以显示单击控件(不是选项卡控件)的左上角坐标。
问题
所有容器都会发生这种情况,例如 TabPage
或 Panel
或 Form
以将 PropertyGrid
显示在视图中,并且该行为是因为 [=23 中的代码=] 构造函数,行 259
:
SetActiveControlInternal(gridView);
解决方案是设置表单的活动控件,或者当您需要滚动到容器到特定位置时。
如果表单和标签页都滚动,您可能需要这两个修复。
TabPage滚动时
当您的标签页滚动时,要解决此问题,您可以在所选标签更改时滚动到 (0,0)
:
private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
}
表单滚动时
如果表单滚动了,你可以再次滚动它来显示标签页:
private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
this.ScrollControlIntoView(tabControl);
}
备注
- 您还可以使用以下方法将此更正限制在您的特定选项卡中:
//Suppose tabPage2 is the name of tab page that contains the PropertyGrid
if (tabControl.SelectedTab == this.tabPage2)
您的预期结果
我认为解决问题取决于布局,对于您的具体情况,我使用此代码来获得您的预期结果:
tabControl.SelectedIndexChanged += (sender, e) =>
{
if (tabControl.SelectedIndex == 4)
{
this.AutoScrollPosition = new Point(0,0);
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
}
};
但我认为使用下面的代码是更自然的解决方案,因为当使用上面的代码时,如果您最小化并恢复 windows,您将得到下面代码的结果。
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
this.ScrollControlIntoView(tabControl);
我的 .NET Forms 应用程序中的 PropertyGrid 控件出现问题。
我尝试在 AutoScroll 属性 设置为 true 的表单上放置一个 ProperyGrid。
当PropertyGrid位于Form的显示区域内时,就OK了。
但是,当 PropertyGrid 位于 Form 的显示区域之外时,PropertyGrid 会导致意外滚动。
我很难用文字描述这个问题。
这是重现此问题的代码。
using System.Drawing;
using System.Windows.Forms;
namespace PropertyGridAutoScrollProblem
{
public partial class Form1 : Form
{
public Form1()
{
//InitializeComponent();
Control[] controls = new Control[]
{
new TextBox(),
new RadioButton(),
new ListBox(),
new ListView(),
new PropertyGrid() { SelectedObject = this },
new DataGridView(),
};
var tabControl = new TabControl();
tabControl.Size = new Size(400, 400);
tabControl.Location = new Point(50, 50);
this.Controls.Add(tabControl);
foreach (var control in controls)
{
control.Location = new Point(50, 250);
control.Size = new Size(200, 100);
var tabPage = new TabPage(control.GetType().Name);
tabPage.Controls.Add(control);
tabControl.Controls.Add(tabPage);
}
this.AutoScroll = true;
this.ClientSize = new Size(400, 200);
}
}
}
这个程序有一些标签。
每个选项卡包含一个与其选项卡名称相关且位于窗体显示区域之外的控件。
如果您单击 "PropertyGrid" 以外的任何选项卡,则不会发生滚动。
但是,如果您单击 "PropertyGrid" 选项卡,则会发生意外滚动。
These are the screenshots of this program.
最后一个(右下角)屏幕截图是在单击 "PropertyGrid" 之后。
有什么方法可以避免意外滚动吗?
更新 1:
Here is the screenshots I tried and expected.
更新2:
@RezaAghaei 谢谢你的解决方案,但它对我来说并不完美..
我的预期结果是 "no scrolling occurred"。
Here is the screenshots I tried and expected.
更新3:
@RezaAghaei 谢谢你的回复。
据我了解,当我们取消select 表单并再次select 时,表单会滚动以通过 AutoScroll 默认行为显示焦点控件的左上角坐标。
而且,如果我单击第二个选项卡,选项卡控件将获得焦点。
我觉得这对我来说很自然。
如果我在 select 选项卡后单击选项卡页面上的任何控件,单击的控件将获得焦点,而选项卡控件将失去焦点。
在这种情况下,如果我 deselect 表单并再次 select ,表单将滚动以显示单击控件(不是选项卡控件)的左上角坐标。
问题
所有容器都会发生这种情况,例如 TabPage
或 Panel
或 Form
以将 PropertyGrid
显示在视图中,并且该行为是因为 [=23 中的代码=] 构造函数,行 259
:
SetActiveControlInternal(gridView);
解决方案是设置表单的活动控件,或者当您需要滚动到容器到特定位置时。
如果表单和标签页都滚动,您可能需要这两个修复。
TabPage滚动时
当您的标签页滚动时,要解决此问题,您可以在所选标签更改时滚动到 (0,0)
:
private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
}
表单滚动时
如果表单滚动了,你可以再次滚动它来显示标签页:
private void tabControl_SelectedIndexChanged(object sender, EventArgs e)
{
this.ScrollControlIntoView(tabControl);
}
备注
- 您还可以使用以下方法将此更正限制在您的特定选项卡中:
//Suppose tabPage2 is the name of tab page that contains the PropertyGrid
if (tabControl.SelectedTab == this.tabPage2)
您的预期结果
我认为解决问题取决于布局,对于您的具体情况,我使用此代码来获得您的预期结果:
tabControl.SelectedIndexChanged += (sender, e) =>
{
if (tabControl.SelectedIndex == 4)
{
this.AutoScrollPosition = new Point(0,0);
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
}
};
但我认为使用下面的代码是更自然的解决方案,因为当使用上面的代码时,如果您最小化并恢复 windows,您将得到下面代码的结果。
tabControl.SelectedTab.AutoScrollPosition = new Point(0, 0);
this.ScrollControlIntoView(tabControl);