【发布时间】:2021-10-04 11:30:44
【问题描述】:
我基于描述控件各种设置的字典以编程方式添加一系列控件。这里以其中两个条目为例(我截断了其余条目以节省空间):
// Translation array from fix shortname to various data about them
private Dictionary<string, Dictionary<string, string>> fixers = new Dictionary<string, Dictionary<string, string>>
{
["F1"] = new Dictionary<string,string> {
["PrefName"] = "KillF1UnhelpfulHelp",
["Img"] = @"/graphics/F1key.png",
["Title"] = @"Diable F1 ""Help"" function",
["Description"] = @"
Have you ever hit the F1 key by accident and had a distracting and unhelpful window or webpage open as a result?
Windows set the F1 key to a generic help function that basically never helps and always gets in the way.
Enable this control to disable that obnoxious design choice. Note that some programs still respond to F1 on their own accord,
but this will stop the default Windows behavior in things like Windows Explorer at least.
",
["Tags"] = "#Keyboard,#Rage"
},
["CMD"] = new Dictionary<string, string>
{
["PrefName"] = "RestoreAdminCMDContext",
["Img"] = @"/graphics/CMD.png",
["Title"] = @"Restore ""Open Admin CMD Window Here"" to Windows Explorer",
["Description"] = @"
When you need to run commands in CMD, it's usually in a specific folder. Windows used to have an option when you CTRL+Right Click
to show ""Open CMD HERE"" on a folder. This restores that function AND it's at administrative level (and you don't need to CTRL+CLICK to see it)
",
["Tags"] = "#Windows Explorer,#TimeSaver"
},
}
控件本身只是带有一些网格组件、按钮等的自定义框。相当简单。它们目前已正确生成,然后按如下方式添加到窗口中:
添加它们的代码:
public MainWindow()
{
InitializeComponent();
var fixNames = fixers.FixerNames();
foreach (string key in fixNames)
{
var temp = fixers.GetFix(key);
// Be sure to pass this along as well
temp["Name"] = key;
fixerBoxes[key] = new FixerBox(temp);
FixersArea.Children.Add(fixerBoxes[key]);
}
FixerBox f1box = (FixerBox)FixersArea.FindName("F1");
StatusBox.Text += "Tags are:"+ f1box.FixerTags;
}
这是添加控件的窗口的 XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="60"/>
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Name="StatusBox" Width="600" MinHeight="40" Background="Beige"/>
<ScrollViewer Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Visible">
<WrapPanel Name="FixersArea" Orientation="Horizontal" Width="auto" ></WrapPanel>
</ScrollViewer>
</Grid>
这是输出:
一切都按预期工作,但是如何引用动态生成的自定义控件?我尝试了几种通过名称或其他值引用它的方法,并通过将一些文本打印到状态框来进行测试:
FixerBox f1box = (FixerBox)FixersArea.FindName("F1");
StatusBox.Text += "Tags are:" + f1box.FixerTags;
但这会导致一个异常,指出 f1box 为空。所以取景器不工作。我在网上找到了一些按名称查找子元素的方法,但这些方法也不起作用,而且相当长,所以我将它们排除在外。
底线是我需要获取/设置控件的状态,根据过滤器显示和隐藏它们,并响应它们的点击事件。我可能可以在控件本身中处理点击响应,但其余部分肯定是主窗口的东西(控件将受到过滤和各种保存/加载设置的影响)。
【问题讨论】:
-
为什么不
f1box = fixerBoxes["F1"]? -
我刚才自己就想通了。我从 HTML 的角度来看这个太多了。它工作正常。如果您将其发布为答案(基本上停止引用“文档”并引用现有对象),我会接受它。