locked
Filling ListBox (in windows1) from TextBox in another window (window2) RRS feed

  • Question

  • CONTEXT: Basically I need to take the contents of a TextBox and assign it to my ListBox. The drawback is the two controls are in forms (windows) different.

    The TextBox control is in the form 1 and the ListBox is in the form 2.

    Now every time you write something in my TextBox (window1) I want the same content appears on a line of my ListBox (window2).

    Every time I type something in the textbox, should be assigned to a new line in the ListBox so completely fill line by line.

    SOME DETAILS: The form1, also contains a ListView, which has a column that is filled with the same TextBox that will be assigned to my ListBox in form2.

    I would like some sugeriencias from you.

    The application is developed in VB.Net, WPF application.

    many Thanks

    • Moved by Amanda Zhu Thursday, July 25, 2013 6:28 AM
    Wednesday, July 24, 2013 6:12 PM

Answers

  • Hi,

    multiple ways to achieve that.

    a) The clean way in my eyes: Your data is stored in so called business objects. Forms and other UI stuff is just displaying the business data. So if you build your application with clearly dividing between these layers, then you will end with a design where you have 2 forms that have a reference to the same business object.

    When a change is done to the business object, the business object will also trigger some event (e.g. PropertyChanged) so that all UI elements that are bound somehow know that they have to update themself.

    The big advantage of such a clean design:
    - The forms does not know each other and are not connected to each other.
    - The business objects can easily be unit tested (Something that is harder with UI stuff. Coded UI tests are your friend here of course!)
    - The business objects can easily be reused.

    b) Not so clean but maybe easier to build:
    The first form offers an event when the textbox is changed. The second form will subscribe to this event. That way the second form is dependend of the first form and has to know it. In fact it needs to know all windows that might change a value. That gets quickly quite complex if you get more and more forms. But at least the implementation details are hidden and all the second form needs to know is the event that it has to subscribe to.

    c) Most ugly: You can make the controls and data of the forms public. You can allow that one form modifies the other. So the window1 just need to know the second one and could directly do all changes. Such a solution works technically but from the design point it is the worst solution possible, it will be hard to maintain and you have dependencies between forms. So if one form is changed you might have to change other forms, too.

    So my suggestion is to check out the first thing. Create a class that holds the information. In your small example it is just a class with one property. It could be something like this:

        public class TextStorage : INotifyPropertyChanged, INotifyPropertyChanging
        {
            private string _text;
            public string Text
            {
                get { return _text; }
                set
                {
                    OnPropertyChanging(this, new PropertyChangingEventArgs("Text"));
                    _text = value;
                    OnPropertyChanged(this, new PropertyChangedEventArgs("Text"));
                }
            }

            public event PropertyChangingEventHandler PropertyChanging;
            public event PropertyChangedEventHandler PropertyChanged;

            protected virtual void OnPropertyChanging(object sender, PropertyChangingEventArgs e)
            {
                var handler = PropertyChanging;
                if (handler != null)
                    handler(sender, e);
            }

            protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(sender, e);
            }
        } 

    This is a common pattern as you can see (using 2 interfaces). It is not that common with Windows Forms but with WPF/Silverlight/... it is the common way to implement objects that can be bound to controls.

    With kind regards,

    Konrad

    Thursday, July 25, 2013 6:50 AM

All replies

  • Hello,

    I have moved this thread to WPF forum for better response.

    Best regards,


    Amanda Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, July 25, 2013 6:29 AM
  • Hi,

    multiple ways to achieve that.

    a) The clean way in my eyes: Your data is stored in so called business objects. Forms and other UI stuff is just displaying the business data. So if you build your application with clearly dividing between these layers, then you will end with a design where you have 2 forms that have a reference to the same business object.

    When a change is done to the business object, the business object will also trigger some event (e.g. PropertyChanged) so that all UI elements that are bound somehow know that they have to update themself.

    The big advantage of such a clean design:
    - The forms does not know each other and are not connected to each other.
    - The business objects can easily be unit tested (Something that is harder with UI stuff. Coded UI tests are your friend here of course!)
    - The business objects can easily be reused.

    b) Not so clean but maybe easier to build:
    The first form offers an event when the textbox is changed. The second form will subscribe to this event. That way the second form is dependend of the first form and has to know it. In fact it needs to know all windows that might change a value. That gets quickly quite complex if you get more and more forms. But at least the implementation details are hidden and all the second form needs to know is the event that it has to subscribe to.

    c) Most ugly: You can make the controls and data of the forms public. You can allow that one form modifies the other. So the window1 just need to know the second one and could directly do all changes. Such a solution works technically but from the design point it is the worst solution possible, it will be hard to maintain and you have dependencies between forms. So if one form is changed you might have to change other forms, too.

    So my suggestion is to check out the first thing. Create a class that holds the information. In your small example it is just a class with one property. It could be something like this:

        public class TextStorage : INotifyPropertyChanged, INotifyPropertyChanging
        {
            private string _text;
            public string Text
            {
                get { return _text; }
                set
                {
                    OnPropertyChanging(this, new PropertyChangingEventArgs("Text"));
                    _text = value;
                    OnPropertyChanged(this, new PropertyChangedEventArgs("Text"));
                }
            }

            public event PropertyChangingEventHandler PropertyChanging;
            public event PropertyChangedEventHandler PropertyChanged;

            protected virtual void OnPropertyChanging(object sender, PropertyChangingEventArgs e)
            {
                var handler = PropertyChanging;
                if (handler != null)
                    handler(sender, e);
            }

            protected virtual void OnPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                var handler = PropertyChanged;
                if (handler != null)
                    handler(sender, e);
            }
        } 

    This is a common pattern as you can see (using 2 interfaces). It is not that common with Windows Forms but with WPF/Silverlight/... it is the common way to implement objects that can be bound to controls.

    With kind regards,

    Konrad

    Thursday, July 25, 2013 6:50 AM
  • I don't find what is the difficulty are you facing in it, anyway i will post one of the simplest way to achieve it you can extend in your way.

    window1.xaml

    <Window x:Class="WpfApplication2.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window1" Height="300" Width="300">   
        <Grid x:Name="LayoutRoot">       
            <StackPanel Orientation="Horizontal" Height="25">
                <TextBlock Text="Enter Text"></TextBlock>
                <TextBox x:Name="text" Height="30" Width="150"></TextBox>
                <Button Content="Add" Click="Button_Click"></Button>
            </StackPanel>
        </Grid>
    </Window>
    

    window1.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Threading;
    using System.ComponentModel;
    
    namespace WpfApplication2
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window 
        {
            Window2 _window2 = new Window2();
            public Window1()
            {
                InitializeComponent();
                this.Loaded += new RoutedEventHandler(Window1_Loaded);
    
            }
    
            void Window1_Loaded(object sender, RoutedEventArgs e)
            {
                _window2.Show();
            }
          
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                _window2.lstbx.Items.Add(text.Text);
            }
        }
    }
    

    window2.xaml

    <Window x:Class="WpfApplication2.Window2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="Window2" Height="300" Width="300">
        <Grid>
            <ListBox x:Name="lstbx">
            </ListBox>
        </Grid>
    </Window>
    

    Let me know if am going wrong.


    Thanks & Regards
    Syed Amjad Sr. Silverlight/WPF Developer,
    yahoo : syedamjad6736@yahoo.com, skype : syedamjad.0786.
    Please use Marked as Answer if my post solved your problem and use Vote As Helpful if a post was useful.

    Thursday, July 25, 2013 9:31 AM