【问题标题】:WPF how to access sibling from custom UserControl codeWPF如何从自定义UserControl代码访问兄弟
【发布时间】:2015-12-29 19:45:38
【问题描述】:

如果 WPF WindowUserControl0 包含其他两个控件:

UserControl1 - 具有单独 xaml 和代码隐藏的自定义用户控件

UserControl2 - 具有单独 xaml 和代码隐藏的自定义用户控件

如何从UserControl2 代码隐藏访问/引用UserControl1? 我知道我可以使用this.Parent(继承自FrameworkElement.Parent)从代码隐藏中获取父窗口,也可以通过Window.GetWindow(this) 获取父窗口。但是引用这个同级控件呢?

【问题讨论】:

    标签: c# wpf user-controls wpf-controls siblings


    【解决方案1】:

    我认为这是不好的做法,但仍然很容易实现。将 Usercontrol2 类型的属性添加到 UserControl1,将 Usercontrol1 类型的属性添加到 UserControl2。在 Window 或 UserControl0 构造函数中设置这些属性:

    UserControl1.UserControl2 = UserControl2;
    UserControl2.UserControl1 = UserControl1;
    

    确保 UserControl 在 Window.xaml 中有名称(此处的名称 UserControl1 和 UserControl2 仅作为示例)

    【讨论】:

    • 对不起,我上次的评论是错误的,我删除了它。您的回答实际上对我有用,谢谢。您还提到这是不好的做法。那么什么是好的做法呢?
    • 好的做法是使用 MVVM,使用绑定并让模型相互链接,而不是控制自己。例如,它允许您单独使用这些控件进行测试。如果控件需要相互链接,那么将它们拆分为单独的控件是没有意义的。
    • 另外,在某些情况下,这项工作可以在 Window 的 xaml 中完成,使用样式和触发器。
    • 我拆分它们是因为我的 Control2 实际上是一个实时图像(SharpDX Direct2D 图像具有自己的渲染逻辑),其渲染取决于 Control1 中的输入内容。而且我不知道如何将MVVM与Direct2D一起实现,可能只是我的经验不足。
    • 我也不知道,但通常我通过为控件创建依赖属性并在上述场景之一中使用它们来做到这一点。
    【解决方案2】:

    为每个控件命名,更准确地说是x:Name

    例子:

    <UserControl0 x:Name="control0">
      <StackPanel>
        <UserControl1 x:Name="control1"/>
        <UserControl2 x:Name="control2"/>
      </StackPanel>
    </UserControl0>
    

    通过 UserControl0.cs 中的代码隐藏,您可以访问 control1control2

    如果您希望 UserControl2 在这种情况下访问 UserControl1,您可以在定义 UserControl0 的窗口中创建一个实例变量。

    public static MainWindow Instance;
    public MainWindow () {
        Instance = this;
    

    访问方式:

    App.MainWindow.Instance.control1
    

    【讨论】:

    • 好吧,在您的示例中,我只能从 UserControl0 代码隐藏中访问 control1control2 名称。但我实际上需要从UserControl2 代码隐藏访问control1(这是一个单独的代码,它对control1 代码和UserControl0 代码一无所知,尽管它可以通过我提到的方法获得父级)。我的问题是UserControl2 代码隐藏中有一些逻辑,这取决于UserControl1 属性的一些变化。
    • 我相信我已经更新了我的答案,以描述您在评论中的内容。
    【解决方案3】:

    在 UserControl1 后面的代码中使用此代码:

        public static T FindParent<T>(DependencyObject child) where T : DependencyObject
        {
            //get parent item
            DependencyObject parentObject = VisualTreeHelper.GetParent(child);
    
            //we've reached the end of the tree
            if (parentObject == null) return null;
    
            //check if the parent matches the type we're looking for
            T parent = parentObject as T;
            if (parent != null)
                return parent;
            else
                return FindParent<T>(parentObject);
        }
    
        public void Show()
        {
            StackPanel container = FindParent<StackPanel>(this);
            UserControl user_control2 = container.Children[1] as UserControl;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 2013-11-03
      • 2019-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多