使用FindName在行定义下的网格中查找控件(标签)的正确方法是什么?



我有这段代码(这不起作用),它接受类型为grid的网格列表和类型为label的标签列表。这将尝试查找标签是否存在,然后更改其属性。

得到NullReferenceException错误:
try
{
var label = (Label)gridlist[i].FindName(labellist[i].Name);
label.Content = (ipaccuracy[i, 0] == true ? @"ⓘ " : "") + toreturn;
label.ToolTip = string.Join(Environment.NewLine, tooltip);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
}

这段代码通过Task.Run()运行,并且是动态UI的一部分。当UI改变时,运行到这段代码的参数(gridlist和labellist)会改变,但我希望它出错,而不是改变UI的错误部分。

我当前的解决方法是:

labellist[i].Content = (ipaccuracy[i, 0] == true ? @"ⓘ " : "") + toreturn;
labellist[i].ToolTip = string.Join(Environment.NewLine, tooltip);

但是这允许UI在Task.Run()被调用以每行更新正确的信息之前几秒钟给出不正确的信息。(当UI改变时,默认文本是"loading";在等待信息加载时)

下面是我创建相关UI的代码:

RowDefinition newrow2 = new RowDefinition();
newrow2.Name = "column2_" + gamename.CleanName() + ip.CleanName();
Debug.WriteLine(newrow2.Name);
newrow2.Height = new GridLength(28);
rows2.Add(newrow2);
game_details_right.RowDefinitions.Add(newrow2);
var g2 = new Grid { Name = "column2_" + gamename.CleanName() + ip.CleanName() + "_grid", };
active_gridlist.Add(g2);
var l2 = new Label
{
Name = "column2_" + gamename.CleanName() + ip.CleanName() + "_text",
Content = "Loading",
};
Debug.WriteLine("column2_" + gamename.CleanName() + ip.CleanName() + "_text");
listlabelsping.Add(l2);
g2.Children.Add(l2);
game_details_right.Children.Add(g2);
Grid.SetRow(g2, s + 1);
s++;
Task.Run(() =>
{
UpdatePingRead(active_iplist, active_ipaccuracy, listlabelsping, active_gridlist.ToArray());
});

根据我对代码的预期,以下是控件的层次结构。

<Grid Name="game_details_right">
<Grid.RowDefinitions>
<RowDefinition Name="column2_game_19216800" Height="*"/>
...
<Grid.RowDefinitions/>
<Grid Grid.Row="0" Name="column2_game_19216800_grid">
<Label Name="column2_game_19216800_text" Content="thing"/>
</Grid>
...
</Grid>

我做错了什么与FindName?我已经确认我使用了正确的名称,我没有使用标签列表,而是将相同的参数从构造函数传递给Task。

代码说明:我有一个IP地址列表,我每隔X秒ping一次。列表根据用户想要看到的内容而变化。ping服务器是浪费的,结果不会给用户。每当用户在组合框中更改其选择时,该列表都会更新。ping在Task.Run()中运行,因此它在等待服务器反馈时不会占用UI。这还有一个额外的好处,即确保ping总是在设置的间隔内尝试,并使任何具有时间增量的数学方程保持相对准确。

bug代码链接。修复(和更清晰)代码的链接。

这里的主要问题是FindName()只搜索控件的注册名称。XAML硬编码控件应该有这个自动设置(如果您命名它们)。但是,通过编程方式创建的控件需要使用RegisterName(name, object)进行注册。

我在构造函数的末尾添加了这个,然后忽略了NullReferenceException断点。

RegisterName(l2.Name,l2);
RegisterName(g2.Name,g2);
RegisterName(newrow2.Name,newrow2);

这个解决了我的问题。

相关内容

  • 没有找到相关文章

最新更新