Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF如何从自定义UserControl代码访问同级_C#_Wpf_User Controls_Wpf Controls_Siblings - Fatal编程技术网

C# WPF如何从自定义UserControl代码访问同级

C# WPF如何从自定义UserControl代码访问同级,c#,wpf,user-controls,wpf-controls,siblings,C#,Wpf,User Controls,Wpf Controls,Siblings,如果存在包含两个其他控件的WPF窗口或用户控件0: UserControl1-具有单独xaml和代码隐藏的自定义用户控件 UserControl2-具有单独xaml和代码隐藏的自定义用户控件 如何从UserControl2代码隐藏中访问/引用UserControl1? 我知道我可以通过使用this.parent(继承自FrameworkElement.parent)从代码隐藏中获取父窗口,也可以通过window.GetWindow(this)获取父窗口。但是引用这个同级控件怎么样?给每个控件一个

如果存在包含两个其他控件的WPF
窗口
用户控件0

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

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

如何从
UserControl2
代码隐藏中访问/引用
UserControl1

我知道我可以通过使用
this.parent
(继承自
FrameworkElement.parent
)从代码隐藏中获取父窗口,也可以通过
window.GetWindow(this)
获取父窗口。但是引用这个同级控件怎么样?

给每个控件一个名称,更准确地说是
x:name

例如:

<UserControl0 x:Name="control0">
  <StackPanel>
    <UserControl1 x:Name="control1"/>
    <UserControl2 x:Name="control2"/>
  </StackPanel>
</UserControl0>
访问权限,如:

App.MainWindow.Instance.control1

我认为这是不好的做法,仍然很容易做到。将Usercontrol2类型的属性添加到UserControl1,并将UserControl1类型的属性添加到Usercontrol2。在窗口或UserControl0构造函数中设置以下属性:

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

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

在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;
    }
公共静态T FindParent(DependencyObject子对象),其中T:DependencyObject
{
//获取父项
DependencyObject parentObject=VisualTreeHelper.GetParent(子级);
//我们已经到了树的尽头
if(parentObject==null)返回null;
//检查父项是否与我们要查找的类型匹配
T parent=parentObject作为T;
如果(父项!=null)
返回父母;
其他的
返回FindParent(parentObject);
}
公开展览(
{
StackPanel容器=FindParent(此);
UserControl user_control2=container.Children[1]作为UserControl;
}

好吧,在您的示例中,我只能从
UserControl0
code-behind访问
control1
control2
名称。但是我实际上需要从
UserControl2
code-behind访问
control1
(这是一个单独的代码,它对
control1
代码和
UserControl0
代码一无所知,尽管它可以通过我提到的方法获得父代码)。我的问题是
UserControl2
code中有一些逻辑,这取决于
UserControl1
属性的变化。我相信我已经更新了我的答案,以描述您在评论中的内容。很抱歉,我上次的评论是错误的,我删除了它。你的回答确实对我有用,谢谢。你还提到这是一种不好的做法。那么什么才是好的实践呢?好的实践是使用MVVM,使用绑定,让模型之间有链接,而不是控件本身。例如,它允许您单独使用这些控件进行测试。如果控件之间需要有链接,那么将它们拆分为单独的控件是毫无意义的。此外,在某些情况下,这项工作可以在Window的xaml中使用样式和触发器来完成。我之所以拆分它们,是因为我的Control2实际上是一个实时图像(具有自己渲染逻辑的SharpDX Direct2D图像),其呈现取决于Control1中输入的内容。我不知道如何将MVVM与Direct2D一起实现,也许这只是我的经验不足。我也不知道,但通常我是通过为控件创建依赖属性并在上面的某个场景中使用它们来实现的。
    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;
    }