rainit2006 / C-Program

C# Program knowledge
0 stars 0 forks source link

WPF-- 玩转ListBox #18

Open rainit2006 opened 7 years ago

rainit2006 commented 7 years ago

代码:https://drive.google.com/drive/u/0/folders/0B3d5yQ5lBDHGWV9DQmszWEVVa0U

--- Sample: ----- xaml里定义一个ListBox的Style。这个ListBox里包含了textbox, button等控件

<Style x:Key="listboxStyle" 
               TargetType="ListBox">
            <Setter Property="Height"
                        Value="Auto"/>
            <Setter Property="Height"
                        Value="Auto"/>
            <Setter Property="Margin"
                        Value="0,20,0,0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition/>
                                <RowDefinition/>
                                <RowDefinition/>
                            </Grid.RowDefinitions>
                            <StackPanel Grid.Row="0" x:Name="GroupItemsPanel" Background="Yellow">
                                <TextBlock Text="TextBlock"/>
                                <TextBox Text="Textbox" />
                                <Button Content="Button" Click="AddItem"/>
                                <Rectangle Fill="LightBlue" Height="20" Width="100" Margin="2,2,2,2"/>
                                <Ellipse Fill="Coral" Height="20" Width="150" Margin="2,2,2,2"/>
                            </StackPanel>
                            <ItemsPresenter Grid.Row="1"/>
                            <!--Button Grid.Row="2" Width="100" Height="30" Content="Add" Click="AddListItem" /-->
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

再定义一个ListItem的Style。每个Item里包含textblock,textbox等控件。

<Style x:Key="listItemStyle" 
               TargetType="ListBoxItem">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <StackPanel x:Name="GroupItemsPanel" Orientation="Horizontal">
                            <TextBlock Padding="5,0,5,0" Text="{Binding FirstName}" />
                            <TextBlock Text="{Binding LastName}" />
                            <TextBlock Text=", " />
                            <TextBlock Text="{Binding Address}" />
                            <TextBox Text="{Binding Textbox1, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="150" />
                            <!--TextBox Text="{Binding Textbox2}" /-->
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

在cs里定义数据源Model类

class Model
    {
       public string NameContent {get; set;}
        public Customers Customers { get; set; } // 这个是ListBox的ItemSource里要绑定的数据对象。
    }

    public class Customer: INotifyPropertyChanged
    {
        public String FirstName { get; set; }
        public String LastName { get; set; }
        public String Address { get; set; }

        private string textbox1;
        //private static Customer customer;

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public string Textbox1
        {
            get
            {
                //Console.WriteLine("textbox1:"+textbox1);
                return textbox1;
            }
            set
            {
                textbox1 = value;
                OnPropertyChanged("Textbox1");
            }
        }

      public Customer(String firstName, String lastName, String address, String textbox1)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Address = address;
            this.Textbox1 = textbox1;
        }

    }

   // Cutomers类是Customer的集合,将会绑定到ListBox里。
    public class Customers : ObservableCollection<Customer>
    {
        public Customers()
         {
             Add(new Customer("Michael1", "Anderberg1",
                     "12 North Third Street, Apartment 45", "1"));
             Add(new Customer("Chris1", "Ashton1",
                     "34 West Fifth Street, Apartment 67", "2"));
             Add(new Customer("Cassie1", "Hicks1",
                     "56 East Seventh Street, Apartment 89", "3"));
             Add(new Customer("Guido1", "Pica1",
                     "78 South Ninth Street, Apartment 10", "4"));
           }
    }

在ListBox控件里指定上面定义的Style,和DataSource。 <ListBox Name="listbox1" ItemsSource="{Binding Path=Customers}" Style="{StaticResource listboxStyle}" ItemContainerStyle="{StaticResource listItemStyle}"/>

rainit2006 commented 7 years ago

点击ListBox里包含的button,让ListBox添加item元素

private void AddItem(object sender, RoutedEventArgs e)
        {
            DependencyObject dpo = sender as DependencyObject;

            if (dpo != null)
            {
                var ruleItemListBox = VisualTreeUtilities.FindVisualParent<ListBox>(dpo);
                ObservableCollection<Customer> groupDataSource = ruleItemListBox.ItemsSource as ObservableCollection<Customer>;
                groupDataSource.Add(new Customer("New", "new1",
                     "xxxxxx, xxxxx", "10"));
            }
        }

其中VisualTreeUtilities.FindVisualParent函数是自定义的类和函数,里面实际上用到的是:

public static class VisualTreeUtilities
    {
        public static parentControl FindVisualParent<parentControl>(DependencyObject obj) where parentControl : DependencyObject
        {
            if (null == obj)
            {
                return null;
            }

            DependencyObject parent = VisualTreeHelper.GetParent(obj);
            if (null != parent && parent is parentControl)
            {
                return (parentControl)parent;
            }
            else
            {
                parentControl parentOfParent = FindVisualParent<parentControl>(parent);
                if (null != parentOfParent)
                {
                    return parentOfParent;
                }
            }

            return null;
        }