使用 FindName 在行定义下的网格中查找控件(标签)的正确方法是什么?
What is the proper way of finding a control(label) in a grid under row definitions using FindName?
我有这段代码(不起作用)接受网格类型的网格列表和标签类型的标签列表。这会尝试查找标签是否存在,然后更改其属性。
错误: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 更改时,运行 此代码(网格列表和标签列表)的参数更改但我希望它出错而不是更改 UI.[=16 的错误部分=]
我目前的解决方法是:
labellist[i].Content = (ipaccuracy[i, 0] == true ? @"ⓘ " : "") + toreturn;
labellist[i].ToolTip = string.Join(Environment.NewLine, tooltip);
但这允许 UI 在调用 Task.Run() 以每行更新正确信息之前的几秒钟内提供不正确的信息。 (当 UI 更改时,默认文本为“正在加载”,同时等待信息加载)
这是我如何创建相关的代码 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 时做错了什么?我已经确认我使用了正确的名称,而不是使用标签列表,我将相同的参数从构造函数传递给任务。
代码解释:
我有一个 IP 地址列表,我每 X 秒 ping 一次。该列表根据用户希望看到的内容而变化。不向用户提供结果的 ping 服务器是一种浪费。每次用户在组合框中更改他们的选择时,列表都会更新。 pinger 在 Task.Run() 中 运行,因此它在等待服务器反馈时不会占用 UI。这样做的额外好处是确保始终在设定的时间间隔内尝试执行 ping,并使任何具有时间增量的数学方程式保持相对准确。
这里的主要问题是 FindName() 只搜索控件的注册名称。 XAML 硬编码控件应该自动设置(如果你给它们命名)。但是,需要使用 RegisterName(name, object).
注册以编程方式创建的控件
我在构造函数的末尾添加了它,然后忽略了 NullReferenceException 断点。
RegisterName(l2.Name,l2);
RegisterName(g2.Name,g2);
RegisterName(newrow2.Name,newrow2);
这解决了我的问题。
我有这段代码(不起作用)接受网格类型的网格列表和标签类型的标签列表。这会尝试查找标签是否存在,然后更改其属性。
错误: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 更改时,运行 此代码(网格列表和标签列表)的参数更改但我希望它出错而不是更改 UI.[=16 的错误部分=]
我目前的解决方法是:
labellist[i].Content = (ipaccuracy[i, 0] == true ? @"ⓘ " : "") + toreturn;
labellist[i].ToolTip = string.Join(Environment.NewLine, tooltip);
但这允许 UI 在调用 Task.Run() 以每行更新正确信息之前的几秒钟内提供不正确的信息。 (当 UI 更改时,默认文本为“正在加载”,同时等待信息加载)
这是我如何创建相关的代码 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 时做错了什么?我已经确认我使用了正确的名称,而不是使用标签列表,我将相同的参数从构造函数传递给任务。
代码解释: 我有一个 IP 地址列表,我每 X 秒 ping 一次。该列表根据用户希望看到的内容而变化。不向用户提供结果的 ping 服务器是一种浪费。每次用户在组合框中更改他们的选择时,列表都会更新。 pinger 在 Task.Run() 中 运行,因此它在等待服务器反馈时不会占用 UI。这样做的额外好处是确保始终在设定的时间间隔内尝试执行 ping,并使任何具有时间增量的数学方程式保持相对准确。
这里的主要问题是 FindName() 只搜索控件的注册名称。 XAML 硬编码控件应该自动设置(如果你给它们命名)。但是,需要使用 RegisterName(name, object).
注册以编程方式创建的控件我在构造函数的末尾添加了它,然后忽略了 NullReferenceException 断点。
RegisterName(l2.Name,l2);
RegisterName(g2.Name,g2);
RegisterName(newrow2.Name,newrow2);
这解决了我的问题。