如何从加载到子窗口中的用户控件按钮关闭子窗口?

发布于 2024-08-12 17:46:57 字数 998 浏览 4 评论 0原文

这是我的 ChildWindow xaml 代码:

1    <Grid x:Name="LayoutRoot">
2       <Grid x:Name="teste">
3       <Grid.ColumnDefinitions>
4        <ColumnDefinition Width="*"/>
5        <ColumnDefinition Width="*"/>
6       </Grid.ColumnDefinitions>
7       <Grid.RowDefinitions>
8        <RowDefinition />
9        <RowDefinition Height="Auto" />
10      </Grid.RowDefinitions>
11      <local:UserControl1 Grid.Row="0" Grid.ColumnSpan="2"/>
12     </Grid>
13   </Grid>

这是我的 UserControl1 xaml 代码:

1     <Grid x:Name="LayoutRoot" Background="#FFA34444">
2      <Button Click="Child_Close" Content="Cancel">
3     </Grid>

这是我的 UserControl C#:

private void Child_Close(object sender, System.Windows.RoutedEventArgs e)
{
 ChildWindow cw = (ChildWindow)this.Parent;
 cw.Close();
}

尝试这种方式不起作用。 有什么想法吗?

塔克斯 约西

this is my ChildWindow xaml code:

1    <Grid x:Name="LayoutRoot">
2       <Grid x:Name="teste">
3       <Grid.ColumnDefinitions>
4        <ColumnDefinition Width="*"/>
5        <ColumnDefinition Width="*"/>
6       </Grid.ColumnDefinitions>
7       <Grid.RowDefinitions>
8        <RowDefinition />
9        <RowDefinition Height="Auto" />
10      </Grid.RowDefinitions>
11      <local:UserControl1 Grid.Row="0" Grid.ColumnSpan="2"/>
12     </Grid>
13   </Grid>

This is my UserControl1 xaml code:

1     <Grid x:Name="LayoutRoot" Background="#FFA34444">
2      <Button Click="Child_Close" Content="Cancel">
3     </Grid>

This is my UserControl C#:

private void Child_Close(object sender, System.Windows.RoutedEventArgs e)
{
 ChildWindow cw = (ChildWindow)this.Parent;
 cw.Close();
}

Trying this way doesn't work.
Any Idea?

Tks
Josi

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风尘浪孓 2024-08-19 17:46:57

UserControl 的父级的问题不是 ChildWindow,而是子窗口内的 Grid。您需要获取 UserControl 的父级的父级才能导航到 ChildWindow:-

ChildWindow cw = (ChildWindow)((FrameworkElement)this.Parent).Parent;

但是,将其嵌入到您的 UserControl 中是不好的做法,您将向 UserControl 的使用者规定它可以放置的位置。在上述情况下,要使用户控件正常工作,它需要始终是布局根的直接子级。

更好的方法是在视觉树中搜索 ChildWindow。我会使用这个辅助方法(实际上我会将其放在辅助扩展静态类中,但我会在这里保持简单)。

private IEnumerable<DependencyObject> Ancestors()
{
    DependencyObject current = VisualTreeHelper.GetParent(this);
    while (current != null)
    {
        yield return current;
        current = VisualTreeHelper.GetParent(current);
    }
}

现在您可以使用 LINQ 方法来获取 ChildWindow:-

ChildWindow cw = Ancestors().OfType<ChildWindow>().FirstOrDefault();

这将找到您的 UserControl 的第一个祖先,它恰好是 ChildWindow。这允许您的 UserControl 放置在子窗口 XAML 中的任何深度,它仍然会找到正确的对象。

The problem the UserControl's parent is not the ChildWindow, its the Grid inside the child window. You need to get the parent of the parent of the UserControl to navigate to the ChildWindow:-

ChildWindow cw = (ChildWindow)((FrameworkElement)this.Parent).Parent;

However embedding this in your UserControl would bad practice, you would be stipulating to the consumer of your UserControl where the it can be sited. In the above case for the user control to work it would need to always be a direct child of the Layout root.

A better approach would be to search up the visual tree looing for a ChildWindow. I would use this helper method (actually I'd place this in a helper extensions static class but I'll keep it simple here).

private IEnumerable<DependencyObject> Ancestors()
{
    DependencyObject current = VisualTreeHelper.GetParent(this);
    while (current != null)
    {
        yield return current;
        current = VisualTreeHelper.GetParent(current);
    }
}

Now you can use LINQ methods to get the ChildWindow with:-

ChildWindow cw = Ancestors().OfType<ChildWindow>().FirstOrDefault();

This will find the first ancestor of your UserControl that happens to be ChildWindow. This allows your UserControl to be placed at any depth in the child windows XAML, it would still find the correct object.

两人的回忆 2024-08-19 17:46:57

这是我当前的(临时)解决方案 - 一个用于打开弹出窗口的 ChildPopupWindowHelper 静态类,而无需为我想要公开的每个用户控件创建一个愚蠢的 ChildWindow XAML 实例。

  • 照常创建用户控件,继承自 ChildWindowUserControl

  • 然后使用

    打开一个弹出窗口

    ChildPopupWindowHelper.ShowChildWindow("TITLE", new EditFooControl())

我对此并不完全满意,并欢迎对此模式的增强。


public static class ChildPopupWindowHelper
{
    public static void ShowChildWindow(string title, ChildWindowUserControl userControl)
    {
        ChildWindow cw = new ChildWindow()
        {
            Title = title
        };
        cw.Content = userControl;
        cw.Show();
    }
}

public class ChildWindowUserControl : UserControl
{
    public void ClosePopup()
    {
        DependencyObject current = this;
        while (current != null)
        {
            if (current is ChildWindow)
            {
                (current as ChildWindow).Close();
            }

            current = VisualTreeHelper.GetParent(current);
        }
    }
}

Here's my current (temporary) solution - a ChildPopupWindowHelper static class to open popup windows without having to create a stupid ChildWindow XAML instance for every usercontrol I want to expose.

  • Create usercontrol as usual, inheriting from ChildWindowUserControl

  • Then open a popup with

    ChildPopupWindowHelper.ShowChildWindow("TITLE", new EditFooControl())

I'm not completely happy with this and welcome enhancements to this pattern.


public static class ChildPopupWindowHelper
{
    public static void ShowChildWindow(string title, ChildWindowUserControl userControl)
    {
        ChildWindow cw = new ChildWindow()
        {
            Title = title
        };
        cw.Content = userControl;
        cw.Show();
    }
}

public class ChildWindowUserControl : UserControl
{
    public void ClosePopup()
    {
        DependencyObject current = this;
        while (current != null)
        {
            if (current is ChildWindow)
            {
                (current as ChildWindow).Close();
            }

            current = VisualTreeHelper.GetParent(current);
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文