Search code examples
c#wpfwpfdatagrid

WPF add datagrid row from other window


I have an add movie window:

  private void button1_Click(object sender, RoutedEventArgs e)
        {
            string name = txtName.Text;
            string genre = txtGenre.Text;
            bool dubbed = checkBox1.IsChecked.Value;
            bool is3d = checkBox2.IsChecked.Value;
            MessageBox.Show(name + " " + genre);
            var main = new MainWindow();
            main.CallbackAddMovie(name, genre, dubbed, is3d);
            this.Close();
        }

And the callback:

   public class DataItem
        {
            public string name { get; set; }
            public string genre { get; set; }
            public bool dubbed { get; set; }
            public bool is3d { get; set; }
        }

        public void CallbackAddMovie(string mname, string mgenre, bool mdubbed, bool mis3d)
        {
            dataGrid1.Items.Add(new DataItem { name = "Movie name2", genre = "Action", dubbed = true, is3d = true });
            dataGrid1.Items.Add(new DataItem { name = mname, genre = mgenre, dubbed = mdubbed, is3d = mis3d });
            dataGrid1.SelectAll();
        }

When I add a movie, I get the message boxes but the datagrid won't have the new items in it. What is worng?

EDIT:
Here is my datagrid creation:

  var colname = new DataGridTextColumn();
            colname.Header = "Name";
            colname.Binding = new Binding("name");
            dataGrid1.Columns.Add(colname);

            var colgenre = new DataGridTextColumn();
            colgenre.Header = "Genre";
            colgenre.Binding = new Binding("genre");
            dataGrid1.Columns.Add(colgenre);

            var coldubbed = new DataGridCheckBoxColumn();
            coldubbed.Header = "Dubbed";
            coldubbed.Binding = new Binding("dubbed");
            dataGrid1.Columns.Add(coldubbed);

            var col3d = new DataGridCheckBoxColumn();
            col3d.Header = "3D";
            col3d.IsReadOnly = true;
            col3d.Binding = new Binding("is3d");
            dataGrid1.Columns.Add(col3d);


            // create and add two lines of fake data to be displayed, here
            dataGrid1.Items.Add(new DataItem { name = "Movie name", genre = "Action", dubbed = true, is3d = true });

EDIT:
Full project:
MainWindow.cs:
http://pastebin.com/Xrr6DjuH MainWindow.xaml:
http://pastebin.com/SJS4akU4 AddMovie:
http://pastebin.com/J7C5ub8N


Solution

  • Instead of adding items directly to the datagrid using Items.Add(), you should create a collection, like a List<> or ObservableCollection<> and assign it as the datasource of the datagrid. Then instead of adding a new DataItem to the datagrid, simply add a new object to the datasource and the grid will be automatically updated.

    WPF is meant to be used in a MVC pattern, and you are using it more like WinForms.

    EDIT: Here is an example that shows how WPF would work in this situation

    MainWindow.xaml.cs

    public partial class MainWindow : Window
    {
    
        ObservableCollection<ListObject> _listDatasource;
        public MainWindow()
        {
            InitializeComponent();
            _listDatasource = new ObservableCollection<ListObject>();
            listView1.ItemsSource = _listDatasource;
        }
    
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            AddWindow winAdd = new AddWindow();
            winAdd.AddItem += new AddItemHandler(winAdd_AddItem);
            winAdd.Show();
        }
    
        void winAdd_AddItem(object sender, ListObject itemToAdd)
        {
            _listDatasource.Add(itemToAdd);
        }
    }
    

    MainWindow.xaml

    <Grid>
            <ListView Height="163" HorizontalAlignment="Left" Margin="34,56,0,0" Name="listView1" VerticalAlignment="Top" Width="322" >
                <ListView.View>
    
                    <GridView x:Name="gridList" >
                        <GridViewColumn x:Name="colValue"  DisplayMemberBinding="{Binding Path=ListValue}" Header="Value" />
    
                    </GridView>
                </ListView.View>
            </ListView>
            <Button Content="Open Add Window" Height="23" HorizontalAlignment="Left" Margin="47,27,0,0" Name="button1" VerticalAlignment="Top" Width="177" Click="button1_Click" />
        </Grid>
    

    AddWindow.xaml

     <Grid>
            <TextBox Height="23" HorizontalAlignment="Left" Margin="57,71,0,0" Name="textBox1" VerticalAlignment="Top" Width="120" />
            <Label Content="Add this:" Height="28" HorizontalAlignment="Left" Margin="57,46,0,0" Name="label1" VerticalAlignment="Top" />
            <Button Content="Add it" Height="23" HorizontalAlignment="Left" Margin="102,114,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        </Grid>
    

    AddWindow.xaml.cs

     public delegate void AddItemHandler(object sender, ListObject itemToAdd);
    
        public partial class AddWindow : Window
        {
            public event AddItemHandler AddItem;
            public AddWindow()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                ListObject itemToAdd = new ListObject();
                itemToAdd.ListValue = textBox1.Text;
                AddItem(this, itemToAdd);
            }
        }
    

    ListObject.cs

     public class ListObject
        {
            private string _listValue;
    
            public string ListValue
            {
                get { return _listValue; }
                set { _listValue = value; }
            }
        }