locked
Access controls within a ListView RRS feed

  • Question

  • Hi All,

    I have a ListView populated from an Access table, with each ListView item displaying infromation with several TextBlocks.
    I have also placed a CheckBox and TextBox in each item, to collect data from the user.

    On a buton click, I would like to collect the value of the checkbox and textbox, and insert it into another table.
    I have done similar things in the past using DataList in ASP1.1, but I cannot get WPF's ListControl to work in the same mannor.

    Can somebody please send me some code snippets or point me to some good expamles?

    Thanks,

    Glyn 

    Friday, June 5, 2009 9:01 AM

Answers

  • <Window x:Class="Trials.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Height="300"
            Width="300">
        <StackPanel>
            <ListView ItemsSource="{Binding MyItems}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Path=.}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Label Content="Enter some text below and press add" />
            <TextBox Name="userEntry" />
            <Button Click="Button_Click_1">Add</Button>
        </StackPanel>
    </Window>
    XAML shown above.

    The code behind for the above xaml is shown below.

     public partial class Window1 : Window
        {
            public ObservableCollection<string> MyItems { get; set; }
            public Window1()
            {
                InitializeComponent();
                MyItems = new ObservableCollection<string>();
                this.DataContext = this;
            }
    
            public int WindowTitle { get; set; }
    
            /*
            #region Dependency Events
            #region Test
    
            /// <summary>
            /// Test Dependency Property
            /// </summary>
            public static readonly DependencyProperty TestProperty =
                DependencyProperty.Register("Test", typeof(bool), typeof(Window1),
                    new FrameworkPropertyMetadata((bool)false), (x) =>
                                                                   {
                                                                       Debug.WriteLine("Value in callback : " + x);
                                                                       return true; //always valid.
                                                                   });
    
            /// <summary>
            /// Gets or sets the Test property.  This dependency property 
            /// indicates ....
            /// </summary>
            public bool Test
            {
                get { return (bool)GetValue(TestProperty); }
                set { SetValue(TestProperty, value); }
            }
    
            #endregion
    
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            { }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Test = true;
                Test = true;
                txt.IsReadOnly = !txt.IsReadOnly;
            }
            #endregion
            */
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                MyItems.Add(userEntry.Text);
                userEntry.Clear();
            }
        }

    Software Engineer 1, My Blog
    Friday, June 5, 2009 12:12 PM
  • Hi,

     

    -->On a buton click, I would like to collect the value of the checkbox and textbox, and insert it into another table.

     

    You can enumerate all the items container in ListView, then get the TextBox or CheckBox instance in each item container. It is a little tricky that you find the visual child in the visual tree generated by the DataTemplate. The following code segment illustrates how to accomplish this .

     

    Code snippet:

      public void EnumerateTextBoxInListView(ListView listView)

            {

                for (int i = 0; i < listView.Items.Count; i++)

                {

                    //get the item container(ListViewItem)

                    ListViewItem container = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                    if (container != null)

                    {

                        TextBox textBox = GetDescendantByType(container, typeof(TextBox)) as TextBox;

                        if (textBox != null)

                        {

                            //get the text of TextBox

                            var textValue = textBox.Text;

                        }

                    }

                }

            }

            //GetDescendantByType

            public static Visual GetDescendantByType(Visual element, Type type)

            {

                if (element == null) return null;

                if (element.GetType() == type) return element;

                Visual foundElement = null;

                if (element is FrameworkElement)

                    (element as FrameworkElement).ApplyTemplate();

                for (int i = 0;

                    i < VisualTreeHelper.GetChildrenCount(element); i++)

                {

                    Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;

                    foundElement = GetDescendantByType(visual, type);

                    if (foundElement != null)

                        break;

                }

                return foundElement;

            }

     

    -->Can the ObservableCollection be used if my ListView is bound to a database table.

     

    Do you want to use the ObservableCollection for ListView  and set DataTable as the source of ListView at the same time? if so, the answer is no. you can not set the source of ListView twice, if you do this, the latter data source will be source of ListView, the former one will just be ignored.

     

    -->I cannot see how it can be used to collect a TextBox value on an (external) button click, unless the values are stored in some sort of temp table, which seems very cumbersome.


    Ye,  you need get help from a temporary table to save the values from TextBoxs inside ListView.

     

    Hope this helps.
    Thanks.


    Jim Zhou -MSFT
    Wednesday, June 10, 2009 9:43 AM

All replies

  • Hi Glyn123,

    For achieving the functionality mentioned in your thread, you need to use ObservableCollection and bind it to the ListView first.


    Friday, June 5, 2009 11:34 AM
  • <Window x:Class="Trials.Window1"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Height="300"
            Width="300">
        <StackPanel>
            <ListView ItemsSource="{Binding MyItems}">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBox Text="{Binding Path=.}" />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Label Content="Enter some text below and press add" />
            <TextBox Name="userEntry" />
            <Button Click="Button_Click_1">Add</Button>
        </StackPanel>
    </Window>
    XAML shown above.

    The code behind for the above xaml is shown below.

     public partial class Window1 : Window
        {
            public ObservableCollection<string> MyItems { get; set; }
            public Window1()
            {
                InitializeComponent();
                MyItems = new ObservableCollection<string>();
                this.DataContext = this;
            }
    
            public int WindowTitle { get; set; }
    
            /*
            #region Dependency Events
            #region Test
    
            /// <summary>
            /// Test Dependency Property
            /// </summary>
            public static readonly DependencyProperty TestProperty =
                DependencyProperty.Register("Test", typeof(bool), typeof(Window1),
                    new FrameworkPropertyMetadata((bool)false), (x) =>
                                                                   {
                                                                       Debug.WriteLine("Value in callback : " + x);
                                                                       return true; //always valid.
                                                                   });
    
            /// <summary>
            /// Gets or sets the Test property.  This dependency property 
            /// indicates ....
            /// </summary>
            public bool Test
            {
                get { return (bool)GetValue(TestProperty); }
                set { SetValue(TestProperty, value); }
            }
    
            #endregion
    
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            { }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                Test = true;
                Test = true;
                txt.IsReadOnly = !txt.IsReadOnly;
            }
            #endregion
            */
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                MyItems.Add(userEntry.Text);
                userEntry.Clear();
            }
        }

    Software Engineer 1, My Blog
    Friday, June 5, 2009 12:12 PM
  • Thankyou for replying.

    Just to clarify, I need by button to be outside of the ListView, and when clicked, iterate through the list, getting  a textbox value for each row.

    Can the ObservableCollection be used in this situation, as the example that KrishnaBhargava gave, shows the binding in reverse.
    The ListView is bound to 'MyItems' which is set from the code behind.
    Can the ObservableCollection be used if my ListView is bound to a database table.

    Sorry if I've missed something stupid, I'm still new to WPF,

    Thanks,

    Glyn





    Monday, June 8, 2009 8:30 AM
  • Just a quick update,

    I found this article:
    http://wpf-tutorials.livejournal.com/2698.html

    As the ObservableCollection only has the CollectionChanged and PropertyChanged events, I cannot see how it can be used to collect a TextBox value on an (external) button click, unless the values are stored in some sort of temp table, which seems very cumbersome. 
    Monday, June 8, 2009 10:27 AM
  • Hi,

     

    -->On a buton click, I would like to collect the value of the checkbox and textbox, and insert it into another table.

     

    You can enumerate all the items container in ListView, then get the TextBox or CheckBox instance in each item container. It is a little tricky that you find the visual child in the visual tree generated by the DataTemplate. The following code segment illustrates how to accomplish this .

     

    Code snippet:

      public void EnumerateTextBoxInListView(ListView listView)

            {

                for (int i = 0; i < listView.Items.Count; i++)

                {

                    //get the item container(ListViewItem)

                    ListViewItem container = listView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem;

                    if (container != null)

                    {

                        TextBox textBox = GetDescendantByType(container, typeof(TextBox)) as TextBox;

                        if (textBox != null)

                        {

                            //get the text of TextBox

                            var textValue = textBox.Text;

                        }

                    }

                }

            }

            //GetDescendantByType

            public static Visual GetDescendantByType(Visual element, Type type)

            {

                if (element == null) return null;

                if (element.GetType() == type) return element;

                Visual foundElement = null;

                if (element is FrameworkElement)

                    (element as FrameworkElement).ApplyTemplate();

                for (int i = 0;

                    i < VisualTreeHelper.GetChildrenCount(element); i++)

                {

                    Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;

                    foundElement = GetDescendantByType(visual, type);

                    if (foundElement != null)

                        break;

                }

                return foundElement;

            }

     

    -->Can the ObservableCollection be used if my ListView is bound to a database table.

     

    Do you want to use the ObservableCollection for ListView  and set DataTable as the source of ListView at the same time? if so, the answer is no. you can not set the source of ListView twice, if you do this, the latter data source will be source of ListView, the former one will just be ignored.

     

    -->I cannot see how it can be used to collect a TextBox value on an (external) button click, unless the values are stored in some sort of temp table, which seems very cumbersome.


    Ye,  you need get help from a temporary table to save the values from TextBoxs inside ListView.

     

    Hope this helps.
    Thanks.


    Jim Zhou -MSFT
    Wednesday, June 10, 2009 9:43 AM