bes7252

I need a UserControl to call a method on its parent window. What are my options Can I bind a method on the usercontrol to the parent Or is there some other way

Brian



Re: Windows Presentation Foundation (WPF) UserControl call window method

Hamid Mahmood - MSFT

I'm not sure if I understand your scenario. Do you mean that you have a UserControl that is shown in a Window. Lets call this window as Window2. Window2 has an owner Window, Window1. Now, from the UserControl, you want to call an API on Window1



Re: Windows Presentation Foundation (WPF) UserControl call window method

bes7252

I can give you more detail of my situation. I have a UserControl that is shown in a window. The UserControl sits in a spot that is occupied by several controls, but only 1 is visible at a time. The others are collapsed. I've placed a button on the UserControl that should hide itself and make another control visible. Since the button is on the UserControl, I don't know how to refer to other Controls in the Window.

I figured I should just call a method on the Window that does all this work. I'm not sure how to call the method from inside the UserControl's CS file.

Brian





Re: Windows Presentation Foundation (WPF) UserControl call window method

Edmundas

Hello,

This might work

DependencyObject parent = this.Parent;

while (parent != null && !(parent is Window))
parent = LogicalTreeHelper.GetParent(parent);

Window w = parent as Window;

if (w != null)
w.Close();

Edmundas





Re: Windows Presentation Foundation (WPF) UserControl call window method

ivolved_Mike_Brown

I'd recommend using an event, and letting the window handle the event properly.

First define your user control in XAML...here is a simple one to demonstrate.

    1 <UserControl x:Class="WindowsApplication1.UserControl1"

    2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    4     DataContext="UserControl" >

    5   <StackPanel>

    6     <TextBlock Text="{Binding}"/>

    7     <Button

    8       Name="ClickTest"

    9       Click="OnButtonClicked">Click Me!</Button>

   10   </StackPanel>

   11 </UserControl>

Next define your code behind with the event for the window to respond to

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using System.Windows;

    5 using System.Windows.Controls;

    6 using System.Windows.Data;

    7 using System.Windows.Documents;

    8 using System.Windows.Input;

    9 using System.Windows.Media;

   10 using System.Windows.Media.Imaging;

   11 using System.Windows.Navigation;

   12 using System.Windows.Shapes;

   13 

   14 namespace WindowsApplication1

   15 {

   16     /// <summary>

   17     /// Interaction logic for UserControl1.xaml

   18     /// </summary>

   19 

   20     public partial class UserControl1 : System.Windows.Controls.UserControl

   21     {

   22         public UserControl1()

   23         {

   24             InitializeComponent();

   25         }

   26         public static readonly RoutedEvent ShowNextEvent =

   27             EventManager.RegisterRoutedEvent("ShowNext", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(UserControl1));

   28 

   29         void RaiseShowNextEvent()

   30         {

   31             RoutedEventArgs newEventArgs = new RoutedEventArgs(UserControl1.ShowNextEvent);

   32             RaiseEvent(newEventArgs);

   33         }

   34 

   35         public event RoutedEventHandler ShowNext

   36         {

   37             add { AddHandler(ShowNextEvent, value); }

   38             remove { RemoveHandler(ShowNextEvent, value); }

   39         }

   40 

   41         void OnButtonClicked(object sender, RoutedEventArgs e)

   42         {

   43             RaiseShowNextEvent();

   44         }

   45     }

   46 }

First I declare and Register the ShowNextEvent for UserControl1. I then implement the OnButtonClicked handler (tied to button click in the XAML) to raise the event. That's all we need in the control. Next we use it in the application's main window.

    1 <Window x:Class="WindowsApplication1.Window1"

    2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    4     Title="WindowsApplication1" Height="300" Width="300"

    5     >

    6   <StackPanel

    7     Orientation="Vertical"

    8     Name="stkMain"/>

    9 </Window>

It's a pretty bare window with just a StackPanel...the magic comes in the code-behind.

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Text;

    4 using System.Windows;

    5 using System.Windows.Controls;

    6 using System.Windows.Data;

    7 using System.Windows.Documents;

    8 using System.Windows.Input;

    9 using System.Windows.Media;

   10 using System.Windows.Media.Imaging;

   11 using System.Windows.Shapes;

   12 

   13 

   14 namespace WindowsApplication1

   15 {

   16     /// <summary>

   17     /// Interaction logic for Window1.xaml

   18     /// </summary>

   19 

   20     public partial class Window1 : System.Windows.Window

   21     {

   22         private UIElementCollection _UserControls;

   23         private int _CurrentControlIndex=0;

   24         private int _Length=5;

   25         public Window1()

   26         {

   27             InitializeComponent();

   28             _UserControls = stkMain.Children;

   29             for (int i = 0; i < _Length; i++)

   30             {

   31                 UserControl1 uc = new UserControl1();

   32                 uc.DataContext = string.Format("This is Control {0}", i);

   33                 uc.ShowNext += new RoutedEventHandler(ShowNextControl);

   34                 _UserControls.Add(uc);

   35                 //stkMain.Children.Add(uc);

   36                 uc.Visibility = Visibility.Collapsed;

   37             }

   38 

   39             _UserControls[0].Visibility = Visibility.Visible;

   40         }

   41 

   42         void ShowNextControl(object sender, RoutedEventArgs e)

   43         {

   44             _UserControls[_CurrentControlIndex].Visibility = Visibility.Collapsed;

   45             _CurrentControlIndex++; //done in a separate line for easier understanding

   46             if (_CurrentControlIndex==_Length)

   47             {

   48                 _CurrentControlIndex = 0;

   49             }

   50             _UserControls[_CurrentControlIndex].Visibility = Visibility.Visible;

   51         }

   52 

   53     }

   54 }

We declare a UIElementCollection, and two integers, one that holds the index of the current control we want to display, another that holds the lenght of the number of controls we are holding. In the constructor, we assign the UIElementCollection to the one held by the Children property of the StackPanel, and create X number of UserControls (X being defined by the _Length variable). We register a handler for the ShowNext event for each control and add it to the Children of the StackPanel.

Finally the ShowNextControl handler collapses the current control and shows the next one...wrapping around to the first if we're at the end.