locked
How to pass object from popup to its parent ? RRS feed

  • Question

  • Hi, In my app there is one textblock and button in a page (Page1.xaml). When user clicks the button a popup is shown and popup (usercontrol mypopup.xaml) has listview. User will select the value(s) as listview allows multiple selection. Now how can I pass the SelectedItems object of listview to parent page (Page1.xaml), so I can read the SelectedItems object and set the text property of textblock ?
    Tuesday, September 25, 2012 12:19 PM

Answers

  • Here comes the example code ;-)

    <Page
        x:Class="App4.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ContentControl Grid.Row="0" x:Name="popUpHost" IsTabStop="False"/>
            <Grid Grid.Row="0" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Button Grid.Row="1" x:Name="GetList" Content="Get list" Click="GetList_Click_1" FontSize="21" Background="Blue" HorizontalAlignment="Center"/>
                <GridView x:Name="myGridView" Grid.Row="0" HorizontalAlignment="Center"/>
            </Grid>
        </Grid>
    </Page>

    -

    using System.Collections.Generic;
    using Windows.Foundation;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Xaml.Shapes;
    
    namespace App4
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
            Popup pu;
            PopupPane pup;
            private void GetList_Click_1(object sender, RoutedEventArgs e)
            {
                myGridView.Items.Clear();
                // ...
                Rect bounds = Window.Current.Bounds;
                double height = bounds.Height;
                double width = bounds.Width;
                pup = new PopupPane();
                pup.Width = bounds.Width;
                pup.Height = bounds.Height;
                // ...
                pu = new Popup();
                pu.IsLightDismissEnabled = true;
                pu.Closed += pu_Closed;
                pu.VerticalOffset = 0.0;
                pu.HorizontalOffset = 0.0;
                pu.HorizontalOffset = 0.0;
                pu.IsOpen = true;
                // ...
                popUpHost.Content = pu;
                pu.Child = pup;
                pu.DataContext = Items.Singleton;
            }
            void pu_Closed(object sender, object e)
            {
                pu.Closed -= pu_Closed;
                // Note : the selected items are returned in order of selection
                // Please adapt to your business case
                pup.ObtainData();
                if (Items.Singleton.List != null)
                    foreach (Rectangle o in Items.Singleton.List)
                        myGridView.Items.Add(new Rectangle() { Fill = o.Fill, Width = 200, Height = 200 });
            }
        }
        /// <summary>
        /// Singleton shuttle for DataContext to/from Popup
        /// </summary>
        public class Items
        {
            private static Items singleton;
            public static Items Singleton
            {
                get
                {
                    if (singleton == null)
                        singleton = new Items();
                    return singleton;
                }
            }
            public IList<object> List { get; set; }
            private Items()
            {
            }
        }
    }

    -

    <UserControl
        x:Class="App4.PopupPane"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
        <Grid Width="300" VerticalAlignment="Stretch" HorizontalAlignment="Left" Background="Yellow">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ListView x:Name="listView1" Grid.Row="0" Width="300" SelectionMode="Multiple">
                <ListView.Header>
                    <TextBlock Text="Selection" FontSize="20" Foreground="Black"/>
                </ListView.Header>
                <Rectangle Height="100" Width="200" Fill="Red"/>
                    <Rectangle Height="100" Width="200" Fill="Orange"/>
                    <Rectangle Height="100" Width="200" Fill="GreenYellow"/>
            </ListView>
            <ListView x:Name="listView2" Grid.Row="1" Width="300" SelectionMode="None">
                <ListView.Header>
                    <TextBlock Text="Previous Selection" FontSize="20" Foreground="Black"/>
                </ListView.Header>
            </ListView>
            <Button Grid.Row="2" Content="Hit to close" Click="ClosePopup" FontSize="21" Background="Blue"/>
        </Grid>
    </UserControl>
    

    -

    using System.Diagnostics;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Shapes;
    
    namespace App4
    {
        sealed partial class PopupPane : UserControl
        {
            Items items;
            public PopupPane()
            {
                InitializeComponent();
                this.Loaded += PopupPane2_Loaded;
            }
            void PopupPane2_Loaded(object sender, RoutedEventArgs e)
            {
                this.Loaded -= PopupPane2_Loaded;
                Debug.WriteLine("[{0}] [DataContext:{1}]", this, this.DataContext);
                this.items = this.DataContext as Items;
                // ...
                if (this.items.List != null)
                    foreach (Rectangle o in this.items.List)
                        listView2.Items.Add(new Rectangle() { Fill = o.Fill, Width = 200, Height = 50 });
    
            }
            private void ClosePopup(object sender, RoutedEventArgs e)
            {
                Popup popup = this.Parent as Popup;
                popup.IsOpen = false;
            }
            public void ObtainData()
            {
                this.items.List = this.listView1.SelectedItems;
            }
        }
    }
    

    -

    Note:

    - Above code is originally meant to shuttle 'anything' [within the 'Items' singleton] between a Parent and a PopUp.

    - It allows to shuttle data 'into' as well as 'fromout' the Popup.

    - It allows to design the Popup in a manner that is independent from the Parent, by applying 'view model' principles to the singleton. 



    • Proposed as answer by Can Bilgin Tuesday, September 25, 2012 3:19 PM
    • Marked as answer by Xyroid Wednesday, September 26, 2012 5:49 AM
    • Edited by ForInfo Wednesday, November 14, 2012 4:10 PM
    Tuesday, September 25, 2012 1:56 PM

All replies

  • How to get data from a popup usercontrol  proposes a method to obtain data back from the popup into the 'main'.

    I would suggest "2.- A variant of the above exists if you don't have [or don't want to use] a MainPage.DataContext referencing a ViewModel:" whereby you use a singleton class to shuttle back the SelectedItems [stored e.g. in a List<object>] into the 'main'

    Tuesday, September 25, 2012 12:33 PM
  • I am sorry, but I am not getting your answer. Can you please give me little demo with help of code ?

    P.S. I am not using MVVM
    Tuesday, September 25, 2012 1:04 PM
  • you don't need to use MVVM for ForInfo's suggestion number 2... Just create a member variable on the page itself or a singleton class like the suggestion, and bind this property to SelectedItems.


    Can Bilgin
    Blog CompuSight

    Tuesday, September 25, 2012 1:42 PM
  • Here comes the example code ;-)

    <Page
        x:Class="App4.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ContentControl Grid.Row="0" x:Name="popUpHost" IsTabStop="False"/>
            <Grid Grid.Row="0" >
                <Grid.RowDefinitions>
                    <RowDefinition Height="*"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Button Grid.Row="1" x:Name="GetList" Content="Get list" Click="GetList_Click_1" FontSize="21" Background="Blue" HorizontalAlignment="Center"/>
                <GridView x:Name="myGridView" Grid.Row="0" HorizontalAlignment="Center"/>
            </Grid>
        </Grid>
    </Page>

    -

    using System.Collections.Generic;
    using Windows.Foundation;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Xaml.Shapes;
    
    namespace App4
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
            Popup pu;
            PopupPane pup;
            private void GetList_Click_1(object sender, RoutedEventArgs e)
            {
                myGridView.Items.Clear();
                // ...
                Rect bounds = Window.Current.Bounds;
                double height = bounds.Height;
                double width = bounds.Width;
                pup = new PopupPane();
                pup.Width = bounds.Width;
                pup.Height = bounds.Height;
                // ...
                pu = new Popup();
                pu.IsLightDismissEnabled = true;
                pu.Closed += pu_Closed;
                pu.VerticalOffset = 0.0;
                pu.HorizontalOffset = 0.0;
                pu.HorizontalOffset = 0.0;
                pu.IsOpen = true;
                // ...
                popUpHost.Content = pu;
                pu.Child = pup;
                pu.DataContext = Items.Singleton;
            }
            void pu_Closed(object sender, object e)
            {
                pu.Closed -= pu_Closed;
                // Note : the selected items are returned in order of selection
                // Please adapt to your business case
                pup.ObtainData();
                if (Items.Singleton.List != null)
                    foreach (Rectangle o in Items.Singleton.List)
                        myGridView.Items.Add(new Rectangle() { Fill = o.Fill, Width = 200, Height = 200 });
            }
        }
        /// <summary>
        /// Singleton shuttle for DataContext to/from Popup
        /// </summary>
        public class Items
        {
            private static Items singleton;
            public static Items Singleton
            {
                get
                {
                    if (singleton == null)
                        singleton = new Items();
                    return singleton;
                }
            }
            public IList<object> List { get; set; }
            private Items()
            {
            }
        }
    }

    -

    <UserControl
        x:Class="App4.PopupPane"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App4"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
        <Grid Width="300" VerticalAlignment="Stretch" HorizontalAlignment="Left" Background="Yellow">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ListView x:Name="listView1" Grid.Row="0" Width="300" SelectionMode="Multiple">
                <ListView.Header>
                    <TextBlock Text="Selection" FontSize="20" Foreground="Black"/>
                </ListView.Header>
                <Rectangle Height="100" Width="200" Fill="Red"/>
                    <Rectangle Height="100" Width="200" Fill="Orange"/>
                    <Rectangle Height="100" Width="200" Fill="GreenYellow"/>
            </ListView>
            <ListView x:Name="listView2" Grid.Row="1" Width="300" SelectionMode="None">
                <ListView.Header>
                    <TextBlock Text="Previous Selection" FontSize="20" Foreground="Black"/>
                </ListView.Header>
            </ListView>
            <Button Grid.Row="2" Content="Hit to close" Click="ClosePopup" FontSize="21" Background="Blue"/>
        </Grid>
    </UserControl>
    

    -

    using System.Diagnostics;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Shapes;
    
    namespace App4
    {
        sealed partial class PopupPane : UserControl
        {
            Items items;
            public PopupPane()
            {
                InitializeComponent();
                this.Loaded += PopupPane2_Loaded;
            }
            void PopupPane2_Loaded(object sender, RoutedEventArgs e)
            {
                this.Loaded -= PopupPane2_Loaded;
                Debug.WriteLine("[{0}] [DataContext:{1}]", this, this.DataContext);
                this.items = this.DataContext as Items;
                // ...
                if (this.items.List != null)
                    foreach (Rectangle o in this.items.List)
                        listView2.Items.Add(new Rectangle() { Fill = o.Fill, Width = 200, Height = 50 });
    
            }
            private void ClosePopup(object sender, RoutedEventArgs e)
            {
                Popup popup = this.Parent as Popup;
                popup.IsOpen = false;
            }
            public void ObtainData()
            {
                this.items.List = this.listView1.SelectedItems;
            }
        }
    }
    

    -

    Note:

    - Above code is originally meant to shuttle 'anything' [within the 'Items' singleton] between a Parent and a PopUp.

    - It allows to shuttle data 'into' as well as 'fromout' the Popup.

    - It allows to design the Popup in a manner that is independent from the Parent, by applying 'view model' principles to the singleton. 



    • Proposed as answer by Can Bilgin Tuesday, September 25, 2012 3:19 PM
    • Marked as answer by Xyroid Wednesday, September 26, 2012 5:49 AM
    • Edited by ForInfo Wednesday, November 14, 2012 4:10 PM
    Tuesday, September 25, 2012 1:56 PM
  • Thanks ForInfo, it worked :)
    Wednesday, September 26, 2012 5:50 AM
  • why not use Windows::UI::Xaml::Controls::Primitives::Popup::tag store a pointer in it and do whatever you want?
    Saturday, December 15, 2012 2:36 AM