我目前有一个WPF项目,它有一个主窗口,以及许多UserControls,它们都是这个Window的子项。这个窗口的许多孩子都是Tabs。我已成功用一个用户控件替换了我的主窗口,该控件实现了与主窗口几乎完全相同的功能。
用UserControl替换Window引入了一个问题 - 目前我们的应用程序通过使用下面显示的Window.FindName
方法确定基于父窗口显示哪个编程选项卡。因此,我需要用我的主要用户控件的适当描述替换Application.Current.MainWindow
。请参阅下面的错误C#方法和选项卡的wpf实例化以获得说明。
注意关于Window.FindName()方法 - 在我用UserControl替换它之后它不起作用的原因是因为FindName方法在可视树中向上搜索as described here 。
有没有人知道如何根据x:Name找到用户控件,类似于Application.Current.MainWindow
?另外,有没有更好的方法来查找UserControl而不是查找x:Name字符串以防它被重命名?
我们目前如何找到MainWindow - 现在需要找到MainUserControl:
(C#)
private static void SetCurrentProgram(int num)
{
Window window = Application.Current.MainWindow;
ProgrammingTab programmingTab1 = window.FindName("ProgrammingTab1") as ProgrammingTab;
ProgrammingTab programmingTab2 = window.FindName("ProgrammingTab2") as ProgrammingTab;
programmingTab1.Visibility = num == 1 ? Visibility.Visible : Visibility.Collapsed;
programmingTab2.Visibility = num == 2 ? Visibility.Visible : Visibility.Collapsed;
}
编程选项卡的实例化。
(xaml)
<Grid>
<ProgrammingControl:ProgrammingTab x:Name="ProgrammingTab1" Program="1" IsVisibleChanged="ProgrammingTab_IsVisibleChanged" />
<ProgrammingControl:ProgrammingTab x:Name="ProgrammingTab2" Program="2" IsVisibleChanged="ProgrammingTab_IsVisibleChanged" />
</Grid>
答案 0 :(得分:2)
听起来您的应用程序是以类似WinForms的风格开发的。要坚持使用该样式并简单回答您的问题,您可以使用FindName()查找UserControl并再次找到ProgrammingTab,如下所示:
var userControl = (MyUserControl)Application.Current.MainWindow.FindName("userControlName");
var programmingTab1 = (ProgrammingTab)userControl.FindName("ProgrammingTab1");
var programmingTab2 = (ProgrammingTab)userControl.FindName("ProgrammingTab2");
...
但是我建议您研究使用WPF的高级功能,例如数据绑定。您可以在静态属性引用的单个对象上使用DependencyProperty“CurrentProgram”,并使用转换器简单地将Visiblity数据绑定到它。
<ProgrammingTab Visibilty="{Binding CurrentProgram,
Source={x:Static MyState.Instance},
Converter={x:Static VisibleIfEqualConverter},
ConverterParameter=1}" ...>
...
通过此更改,您的SetCurrentProgram变得简单:
public void SetCurrentProgram(int num)
{
MyState.Instance.CurrentProgram = num;
}
这种技术的优点在于,每当MyState.Instance.CurrentProgram的值发生变化时,应用程序中任何位置的任何ProgrammingTab都会自动显示或消失,而无需使用FindName()或其他方式找到它们。
答案 1 :(得分:0)
我找到了解决这个问题的方法:我基于另一个StackOverflow用户的算法创建了一个新算法,该算法递归地找到了DependencyObject的任何子项。查找my solution here。如果您在public static class UIHelper {}
中的其他帖子中声明FindChild()方法,则可以通过执行以下操作来解决问题:
ProgrammingTab programmingTab1 = UIHelper.FindChild<ProgrammingTab>(Application.Current.MainWindow, "ProgrammingTab1");
ProgrammingTab programmingTab2 = UIHelper.FindChild<ProgrammingTab>(Application.Current.MainWindow, "ProgrammingTab2");
这仍然使用过程代码而不是声明性XAML来进行像RayBurns建议的绑定。如果它工作,他的解决方案将更有效,因为它不会遍历整个树,而只是改变基于转换器的选项卡的可见性。我现在将测试该解决方案,看看结果如何。
post here中描述了FindName()无法正常工作的原因。
答案 2 :(得分:0)