C# 列表框水平滚动条未正确更新
我有一个表单,其中包含一个listbox控件,以及许多其他确定listbox内容的控件。将项目添加到列表框可以正确设置滚动条的范围,但是更新列表框上的项目(通过此.lstResources.items[index]=myUri)会导致滚动条的范围缩小到超过最大项目的宽度,从而切断最后几个字符。滚动条仍然有效,但以这种方式更新列表框会导致列表中的项目出现意外且不可接受的滚动范围。下面是我如何实现我的列表框:C# 列表框水平滚动条未正确更新,c#,winforms,listbox,scrollbar,C#,Winforms,Listbox,Scrollbar,我有一个表单,其中包含一个listbox控件,以及许多其他确定listbox内容的控件。将项目添加到列表框可以正确设置滚动条的范围,但是更新列表框上的项目(通过此.lstResources.items[index]=myUri)会导致滚动条的范围缩小到超过最大项目的宽度,从而切断最后几个字符。滚动条仍然有效,但以这种方式更新列表框会导致列表中的项目出现意外且不可接受的滚动范围。下面是我如何实现我的列表框: public System.Windows.Forms.ListBox lstResour
public System.Windows.Forms.ListBox lstResources;
this.lstResources = new System.Windows.Forms.ListBox();
this.lstResources.FormattingEnabled = true;
this.lstResources.HorizontalScrollbar = true;
this.lstResources.Location = new System.Drawing.Point(331, 122);
this.lstResources.Name = "lstResources";
this.lstResources.Size = new System.Drawing.Size(307, 316);
this.lstResources.TabIndex = 8;
this.lstResources.Click += new System.EventHandler(this.ResourcesPage.LstResources_Click);
我在此列表框上执行的更改操作如下:
this.parentClassReference.lstResources.Items.Add(myUri);
this.parentClassReference.lstResources.Items[index] = myUri;
this.parentClassReference.lstResources.Items.RemoveAt(index);
我在表单和listbox控件上都尝试过Refresh()和Update(),但都没有任何效果。我到处寻找列表框滚动条的问题,但似乎没有一个有这种特殊的重画问题
它应该是这样的:这就是实际发生的情况:
我有一种感觉,我遗漏了一些明显的东西,或者可能错误地更改了项目,但我对这一点没有什么想法。我对C#和UI设计并不完全陌生,但我也不能说我知道所有的基本控制操作。任何帮助都将不胜感激 编辑1:这是一个示例表单,应该可以重现问题。我开始怀疑StringBuilder可能与更新部分有关,但它也用于btnAdd_单击代码中
public partial class SampleListBoxForm : Form
{
public Dictionary<string, string> CurrentUriQuery { get; set; }
public SampleListBoxForm()
{
this.CurrentUriQuery = new Dictionary<string, string>();
this.InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
this.UpdateParams("sampleApp");
this.listBox1.Items.Add(this.GenerateURI());
this.listBox1.Refresh();
}
private void btnUpdate_Click(object sender, EventArgs e)
{
int index = 0;
this.UpdateParams("sampleApp2");
for (; index < this.listBox1.Items.Count; index++)
{
this.listBox1.Items[index] = this.GenerateURI();
}
}
private void UpdateParams(string filename)
{
this.CurrentUriQuery = new Dictionary<string, string>();
this.CurrentUriQuery["filename"] = filename;
this.CurrentUriQuery["url"] = @"C:\Users\me\Desktop\" + filename;
this.CurrentUriQuery["type"] = "dynamicType";
this.CurrentUriQuery["p1"] = "foo";
this.CurrentUriQuery["p2"] = "bar";
this.CurrentUriQuery["p3"] = "stuff";
this.CurrentUriQuery["p4"] = "test";
}
private string GenerateURI()
{
StringBuilder currentUri = new StringBuilder();
bool firstParam = true;
currentUri.Append(this.CurrentUriQuery["filename"]);
foreach (KeyValuePair<string, string> pair in this.CurrentUriQuery)
{
if (pair.Key != "url" && pair.Key != "filename" && pair.Value != string.Empty && pair.Value != "0")
{
if (firstParam)
{
currentUri.Append("?");
firstParam = false;
}
else
{
currentUri.Append("&");
}
currentUri.Append(pair.Key);
currentUri.Append("=");
currentUri.Append(pair.Value.Replace(" ", ""));
}
}
return currentUri.ToString();
}
public string[] ExtractPathAndQueryFromUriString(string uriString)
{
string[] pathAndQuery = new string[2];
if (uriString.Contains('?'))
{
pathAndQuery[0] = uriString.Split('?')[0];
pathAndQuery[1] = uriString.Split('?')[1];
}
else if (uriString.Contains("%3F"))
{
string[] stringSeparator = new string[] { "%3F" };
pathAndQuery[0] = uriString.Split(stringSeparator, StringSplitOptions.None)[0];
pathAndQuery[1] = uriString.Split(stringSeparator, StringSplitOptions.None)[1];
}
else
{
pathAndQuery[0] = uriString;
pathAndQuery[1] = string.Empty;
}
return pathAndQuery;
}
}
public分部类SampleListBoxForm:Form
{
公共字典CurrentUriQuery{get;set;}
公共样本ListBoxForm()
{
this.CurrentUriQuery=新字典();
this.InitializeComponent();
}
私有void btnAdd_单击(对象发送者,事件参数e)
{
此更新图(“sampleApp”);
this.listBox1.Items.Add(this.GenerateURI());
this.listBox1.Refresh();
}
私有void b更新\单击(对象发送者,事件参数e)
{
int指数=0;
此更新图(“sampleApp2”);
对于(;index
问题似乎出在符号和字符上。添加项目时,它似乎测量正确。当您更新项目时,它不会更新
这个丑陋的黑客似乎是:记录索引,删除项目,将项目插入到记录的索引中
或者切换到DrawMode=OwnerDrawFixed
并计算添加或更改的每个项目的水平范围
值
private void ResizeListBox() {
int maxWidth = 0;
for (int i = 0; i < listBox1.Items.Count; i++) {
int testWidth = TextRenderer.MeasureText(listBox1.Items[i].ToString(),
listBox1.Font, listBox1.ClientSize,
TextFormatFlags.NoPrefix).Width;
if (testWidth > maxWidth)
maxWidth = testWidth;
}
listBox1.HorizontalExtent = maxWidth;
}
publicstaticvoid ResizeListBox()
{
YourListView.HorizontalExtent=TextRenderer.MeasureText(YourListView.Items.ToString(),
YourListView.Font、YourListView.ClientSize、,
TextFormatFlags.NoPrefix).宽度;
}
在窗体加载时调用此函数。。。这可能会解决你的问题。
在这里,只检查第一个listbox元素的宽度,或者您可以使用循环找到最大宽度。无法复制它。更改列表框项目会更改滚动条范围。是否有任何方法跟踪滚动条范围,以便我自己调试它?也许是非公共财产?我会提供更多的代码,但我不认为其余的是相关的。我正在遍历每个列表项来更新它们,但这只是相关外部代码的范围。编辑:知道这些操作没有在与listbox相同的对象中执行可能会有所帮助,这就是为什么listbox是公共的。创建一个新项目,用最少的代码重现问题。把密码贴出来。你在看别人看不到的代码,这让你很难帮上忙。我来试试看,好吗
private void btnAdd_Click(object sender, EventArgs e) {
this.UpdateParams("sampleApp");
this.listBox1.Items.Add(this.GenerateURI());
ResizeListBox();
}
private void btnUpdate_Click(object sender, EventArgs e) {
this.UpdateParams("sampleApp");
for (int index = 0; index < this.listBox1.Items.Count; index++) {
this.listBox1.Items[index] = this.GenerateURI();
}
ResizeListBox();
}
private void listBox1_DrawItem(object sender, DrawItemEventArgs e) {
e.DrawBackground();
if (e.Index > -1) {
Color textColor = SystemColors.WindowText;
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected) {
textColor = SystemColors.HighlightText;
}
TextRenderer.DrawText(e.Graphics, listBox1.Items[e.Index].ToString(),
listBox1.Font, e.Bounds,
textColor, Color.Empty, TextFormatFlags.NoPrefix);
}
}