c# - 如何查找 UserControl 的子项而不是 Window - 替换 Window.FindName

标签 c# wpf user-controls mainwindow findname

我目前有一个 WPF 项目,它有一个主窗口和许多作为该窗口子级的用户控件。此窗口的许多子项都是选项卡。我已经成功地用一个用户控件替换了我的主窗口,它实现了与主窗口几乎完全相同的功能。

用 UserControl 替换 Window 引入了一个问题 - 目前我们的应用程序使用如下所示的 Window.FindName 方法根据父窗口确定要显示哪个编程选项卡。因此,我需要用我的主要用户控件的适当描述替换 Application.Current.MainWindow。请参阅下面的错误 C# 方法和选项卡的 wpf 实例化以进行说明。

关于 Window.FindName() 方法的注意事项 - 在我用 UserControl 替换它后它不起作用的原因是因为 FindName 方法在可视化树中向上搜索,as described here .

有谁知道如何根据 x:Name 查找用户控件,类似于 Application.Current.MainWindow ?此外,是否有比查找 x:Name 字符串更好的方法来查找 UserControl,以防它被重命名?

我们目前如何找到 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>

最佳答案

听起来您的应用程序是以非常类似于 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 的高级功能,例如数据绑定(bind)。您可以在静态属性引用的单例对象上拥有 DependencyProperty“CurrentProgram”,并使用转换器简单地将可见性数据绑定(bind)到它。

<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() 或其他方式找到它们。

关于c# - 如何查找 UserControl 的子项而不是 Window - 替换 Window.FindName,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1758507/

相关文章:

c# - 如何为用户控件属性设置初始值?

c# - 内联函数的 32 字节限制...不是太小了吗?

c# - ModernUI ModernTab 链接点击

c# - Windows 7 更新,导致 WPF 应用程序中出现 "Item has already been added. Key in dictionary: controlbrush"

c# - 动态用户控件更改 - WPF

c# - 如何管理 WinForms UserControl 中的一次性对象?

c# - 为什么 C# 中的字节减法需要强制转换?

c# - C# 中的停靠面板套件不会触发 mousedown 事件

c# - 这个字段怎么为空?

c# - 如何将一个对象的成员绑定(bind)到数据网格