Microsoft Developer Network > Domovská stránka fór > Windows Presentation Foundation (WPF) > Synchronizing column visibility between two different datagrids
Odeslat dotazOdeslat dotaz
 

OdpovědětSynchronizing column visibility between two different datagrids

  • 30. října 2009 22:49John Aschenbrenner Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     
    Hi all, I have written a WPF application that has two datagrids that show up on the same tab at the same time.  One has the direct data results and another has a summary of that data.  Both have the same columns both in name and number.  I have two methods for filtering out, AKA hiding the columns, of the data grid.  One has to do with the way the data is selected to populate the datagrid.  The other is a Context Menu that can be used after the fact to show or hide columns, this is a bit more dynamic.  Now what I need to do is synchronize the name and number of columns showing in both the datagrids.  BTW, in order to get the Context Menu to "Hide" - "Show" columns to work, I had to create a new datagrid class that is derived form the original WPF datagrid. 

    One thing that I have been considering is basing the Column visibility of the Summary datagrid on an object binding but I am having a hard time working out the XAML for that.

    Any ideas on how to best accomplish this?


    Thanks, -ja

Odpovědi

  • 3. listopadu 2009 11:06Zhi-Xin YeMSFT, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Hi John,

    I think the easiest way to synchronize the column visibility between the two DataGrids is, in the method of hiding the columns, find the corresponding columns in the summary DataGrid, and change the Visibility property accordingly, for example:

     private void button1_Click(object sender, RoutedEventArgs e)
            {
                // Hide one of the columns in dataGrid1;
                dataGrid1.Columns[0].Visibility = Visibility.Hidden;
                // Hide the corresponding column in dataGrid2;
                dataGrid2.Columns[0].Visibility = Visibility.Hidden;
            }

    If you want the columns of the two DataGrids to be synchronized via data binding, you can do something like this in code behind:

            void Window1_Loaded(object sender, RoutedEventArgs e)
            {
                ..... other code here.....

                for (int j = 0; j < dataGrid2.Columns.Count; j++)
                {
                    Binding b = new Binding();
                    b.Source = dataGrid1;
                    b.Path = new PropertyPath("Columns[" + j.ToString() + "].Visibility");
                    b.NotifyOnSourceUpdated = true;
                    BindingOperations.SetBinding(dataGrid2.Columns[j], DataGridColumn.VisibilityProperty, b);
                }
            }

    However, I haven't found the corresponding way using XAML.

    If anything is unclear, please feel free to let me know.

    Best Regards,
    Zhi-Xin Ye
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com







    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
  • 4. listopadu 2009 17:21John Aschenbrenner Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     OdpovědětObsahuje kód
    Thanks for your reply Zhi-Xin Ye,

    Unfortunately I had figured it out on my own before I saw your reply.  Here is what I did.  I already had an object that I was using to save the state of the data grid columns.  A very simple object that has the name of the column header and the Visibility of the column.  It is the object value of a serializable dictionary.  I implemented the INotifyPropertyChanged interface on the object.  I then implement the Property Changed Event Handler for all the Summary Data Columns.  I then define the event handler that sets the column visibility correctly.

       public class TestColumns : INotifyPropertyChanged
       {
          string _ColumnName = string.Empty;
          public string ColumnName
          {
             get { return _ColumnName; }
             set 
             { 
                _ColumnName = value;
                OnPropertyChanged("ColumnName");
             }
          }
    
          bool _ColNameIsChecked;
          public bool ColNameIsChecked
          {
             get { return _ColNameIsChecked; }
             set 
             { 
                _ColNameIsChecked = value;
                OnPropertyChanged("ColNameIsChecked");
             }
          }
    
          #region INotifyPropertyChanged Members
    
          public event PropertyChangedEventHandler PropertyChanged;
    
          private void OnPropertyChanged(string propertyName)
          {
             if (PropertyChanged != null)
             {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
             }
          }
    
          #endregion
       }
    
    
    


                   // implement the Property Changed event handler for the Summary Data Grid Columns
                   string module = (from t in tests select t.ToString()).First();
    
                   foreach (TestColumns summaryCol in TestData.Instance.Columns[module])
                   {
                      summaryCol.PropertyChanged += new PropertyChangedEventHandler(summaryCol_PropertyChanged);
                   }
    
    

          void summaryCol_PropertyChanged(object sender, PropertyChangedEventArgs e)
          {
             TestColumns summaryCol = sender as TestColumns;
    
             // hide or show this test column
             DataGridColumn dgCol = (from col in this.SummaryDataGrid.Columns where summaryCol.ColumnName == col.Header as string select col).SingleOrDefault();
             if (dgCol != null)
             {
                dgCol.Visibility = summaryCol.ColNameIsChecked ? Visibility.Visible : Visibility.Hidden;
             }
          }
    
    


    Thanks, -ja

Všechny reakce

  • 3. listopadu 2009 11:06Zhi-Xin YeMSFT, ModerátorUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     Odpovědět
    Hi John,

    I think the easiest way to synchronize the column visibility between the two DataGrids is, in the method of hiding the columns, find the corresponding columns in the summary DataGrid, and change the Visibility property accordingly, for example:

     private void button1_Click(object sender, RoutedEventArgs e)
            {
                // Hide one of the columns in dataGrid1;
                dataGrid1.Columns[0].Visibility = Visibility.Hidden;
                // Hide the corresponding column in dataGrid2;
                dataGrid2.Columns[0].Visibility = Visibility.Hidden;
            }

    If you want the columns of the two DataGrids to be synchronized via data binding, you can do something like this in code behind:

            void Window1_Loaded(object sender, RoutedEventArgs e)
            {
                ..... other code here.....

                for (int j = 0; j < dataGrid2.Columns.Count; j++)
                {
                    Binding b = new Binding();
                    b.Source = dataGrid1;
                    b.Path = new PropertyPath("Columns[" + j.ToString() + "].Visibility");
                    b.NotifyOnSourceUpdated = true;
                    BindingOperations.SetBinding(dataGrid2.Columns[j], DataGridColumn.VisibilityProperty, b);
                }
            }

    However, I haven't found the corresponding way using XAML.

    If anything is unclear, please feel free to let me know.

    Best Regards,
    Zhi-Xin Ye
    MSDN Subscriber Support in Forum
    If you have any feedback on our support, please contact msdnmg@microsoft.com







    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    Welcome to the All-In-One Code Framework!
  • 4. listopadu 2009 17:21John Aschenbrenner Uživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaileUživatelské medaile
     OdpovědětObsahuje kód
    Thanks for your reply Zhi-Xin Ye,

    Unfortunately I had figured it out on my own before I saw your reply.  Here is what I did.  I already had an object that I was using to save the state of the data grid columns.  A very simple object that has the name of the column header and the Visibility of the column.  It is the object value of a serializable dictionary.  I implemented the INotifyPropertyChanged interface on the object.  I then implement the Property Changed Event Handler for all the Summary Data Columns.  I then define the event handler that sets the column visibility correctly.

       public class TestColumns : INotifyPropertyChanged
       {
          string _ColumnName = string.Empty;
          public string ColumnName
          {
             get { return _ColumnName; }
             set 
             { 
                _ColumnName = value;
                OnPropertyChanged("ColumnName");
             }
          }
    
          bool _ColNameIsChecked;
          public bool ColNameIsChecked
          {
             get { return _ColNameIsChecked; }
             set 
             { 
                _ColNameIsChecked = value;
                OnPropertyChanged("ColNameIsChecked");
             }
          }
    
          #region INotifyPropertyChanged Members
    
          public event PropertyChangedEventHandler PropertyChanged;
    
          private void OnPropertyChanged(string propertyName)
          {
             if (PropertyChanged != null)
             {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
             }
          }
    
          #endregion
       }
    
    
    


                   // implement the Property Changed event handler for the Summary Data Grid Columns
                   string module = (from t in tests select t.ToString()).First();
    
                   foreach (TestColumns summaryCol in TestData.Instance.Columns[module])
                   {
                      summaryCol.PropertyChanged += new PropertyChangedEventHandler(summaryCol_PropertyChanged);
                   }
    
    

          void summaryCol_PropertyChanged(object sender, PropertyChangedEventArgs e)
          {
             TestColumns summaryCol = sender as TestColumns;
    
             // hide or show this test column
             DataGridColumn dgCol = (from col in this.SummaryDataGrid.Columns where summaryCol.ColumnName == col.Header as string select col).SingleOrDefault();
             if (dgCol != null)
             {
                dgCol.Visibility = summaryCol.ColNameIsChecked ? Visibility.Visible : Visibility.Hidden;
             }
          }
    
    


    Thanks, -ja